miniassimp
diff include/miniassimp/matrix4x4.inl @ 0:879c81d94345
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 28 Jan 2019 18:19:26 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/include/miniassimp/matrix4x4.inl Mon Jan 28 18:19:26 2019 +0200 1.3 @@ -0,0 +1,686 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2018, assimp team 1.10 + 1.11 + 1.12 + 1.13 +All rights reserved. 1.14 + 1.15 +Redistribution and use of this software in source and binary forms, 1.16 +with or without modification, are permitted provided that the following 1.17 +conditions are met: 1.18 + 1.19 +* Redistributions of source code must retain the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer. 1.22 + 1.23 +* Redistributions in binary form must reproduce the above 1.24 + copyright notice, this list of conditions and the 1.25 + following disclaimer in the documentation and/or other 1.26 + materials provided with the distribution. 1.27 + 1.28 +* Neither the name of the assimp team, nor the names of its 1.29 + contributors may be used to endorse or promote products 1.30 + derived from this software without specific prior 1.31 + written permission of the assimp team. 1.32 + 1.33 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.34 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.35 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.36 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.37 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.38 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.39 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.40 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.41 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.42 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.43 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.44 +--------------------------------------------------------------------------- 1.45 +*/ 1.46 + 1.47 +/** @file matrix4x4.inl 1.48 + * @brief Inline implementation of the 4x4 matrix operators 1.49 + */ 1.50 +#pragma once 1.51 +#ifndef AI_MATRIX4X4_INL_INC 1.52 +#define AI_MATRIX4X4_INL_INC 1.53 + 1.54 +#ifdef __cplusplus 1.55 + 1.56 +#include "matrix4x4.h" 1.57 +#include "matrix3x3.h" 1.58 +#include "quaternion.h" 1.59 + 1.60 +#include <algorithm> 1.61 +#include <limits> 1.62 +#include <cmath> 1.63 + 1.64 +// ---------------------------------------------------------------------------------------- 1.65 +template <typename TReal> 1.66 +aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT : 1.67 + a1(1.0f), a2(), a3(), a4(), 1.68 + b1(), b2(1.0f), b3(), b4(), 1.69 + c1(), c2(), c3(1.0f), c4(), 1.70 + d1(), d2(), d3(), d4(1.0f) 1.71 +{ 1.72 + 1.73 +} 1.74 + 1.75 +// ---------------------------------------------------------------------------------------- 1.76 +template <typename TReal> 1.77 +aiMatrix4x4t<TReal>::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4, 1.78 + TReal _b1, TReal _b2, TReal _b3, TReal _b4, 1.79 + TReal _c1, TReal _c2, TReal _c3, TReal _c4, 1.80 + TReal _d1, TReal _d2, TReal _d3, TReal _d4) : 1.81 + a1(_a1), a2(_a2), a3(_a3), a4(_a4), 1.82 + b1(_b1), b2(_b2), b3(_b3), b4(_b4), 1.83 + c1(_c1), c2(_c2), c3(_c3), c4(_c4), 1.84 + d1(_d1), d2(_d2), d3(_d3), d4(_d4) 1.85 +{ 1.86 + 1.87 +} 1.88 + 1.89 +// ------------------------------------------------------------------------------------------------ 1.90 +template <typename TReal> 1.91 +template <typename TOther> 1.92 +aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const 1.93 +{ 1.94 + return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4), 1.95 + static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4), 1.96 + static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4), 1.97 + static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4)); 1.98 +} 1.99 + 1.100 + 1.101 +// ---------------------------------------------------------------------------------------- 1.102 +template <typename TReal> 1.103 +inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) 1.104 +{ 1.105 + a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0); 1.106 + b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0); 1.107 + c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0); 1.108 + d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0); 1.109 +} 1.110 + 1.111 +// ---------------------------------------------------------------------------------------- 1.112 +template <typename TReal> 1.113 +inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) 1.114 +{ 1.115 + // build a 3x3 rotation matrix 1.116 + aiMatrix3x3t<TReal> m = rotation.GetMatrix(); 1.117 + 1.118 + a1 = m.a1 * scaling.x; 1.119 + a2 = m.a2 * scaling.x; 1.120 + a3 = m.a3 * scaling.x; 1.121 + a4 = position.x; 1.122 + 1.123 + b1 = m.b1 * scaling.y; 1.124 + b2 = m.b2 * scaling.y; 1.125 + b3 = m.b3 * scaling.y; 1.126 + b4 = position.y; 1.127 + 1.128 + c1 = m.c1 * scaling.z; 1.129 + c2 = m.c2 * scaling.z; 1.130 + c3 = m.c3 * scaling.z; 1.131 + c4= position.z; 1.132 + 1.133 + d1 = static_cast<TReal>(0.0); 1.134 + d2 = static_cast<TReal>(0.0); 1.135 + d3 = static_cast<TReal>(0.0); 1.136 + d4 = static_cast<TReal>(1.0); 1.137 +} 1.138 + 1.139 +// ---------------------------------------------------------------------------------------- 1.140 +template <typename TReal> 1.141 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) 1.142 +{ 1.143 + *this = aiMatrix4x4t<TReal>( 1.144 + m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4, 1.145 + m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4, 1.146 + m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4, 1.147 + m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4, 1.148 + m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4, 1.149 + m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4, 1.150 + m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4, 1.151 + m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4, 1.152 + m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4, 1.153 + m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4, 1.154 + m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4, 1.155 + m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4, 1.156 + m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4, 1.157 + m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4, 1.158 + m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4, 1.159 + m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4); 1.160 + return *this; 1.161 +} 1.162 + 1.163 +// ---------------------------------------------------------------------------------------- 1.164 +template <typename TReal> 1.165 +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const 1.166 +{ 1.167 + aiMatrix4x4t<TReal> temp( 1.168 + a1 * aFloat, 1.169 + a2 * aFloat, 1.170 + a3 * aFloat, 1.171 + a4 * aFloat, 1.172 + b1 * aFloat, 1.173 + b2 * aFloat, 1.174 + b3 * aFloat, 1.175 + b4 * aFloat, 1.176 + c1 * aFloat, 1.177 + c2 * aFloat, 1.178 + c3 * aFloat, 1.179 + c4 * aFloat, 1.180 + d1 * aFloat, 1.181 + d2 * aFloat, 1.182 + d3 * aFloat, 1.183 + d4 * aFloat); 1.184 + return temp; 1.185 +} 1.186 + 1.187 +// ---------------------------------------------------------------------------------------- 1.188 +template <typename TReal> 1.189 +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const 1.190 +{ 1.191 + aiMatrix4x4t<TReal> temp( 1.192 + m.a1 + a1, 1.193 + m.a2 + a2, 1.194 + m.a3 + a3, 1.195 + m.a4 + a4, 1.196 + m.b1 + b1, 1.197 + m.b2 + b2, 1.198 + m.b3 + b3, 1.199 + m.b4 + b4, 1.200 + m.c1 + c1, 1.201 + m.c2 + c2, 1.202 + m.c3 + c3, 1.203 + m.c4 + c4, 1.204 + m.d1 + d1, 1.205 + m.d2 + d2, 1.206 + m.d3 + d3, 1.207 + m.d4 + d4); 1.208 + return temp; 1.209 +} 1.210 + 1.211 +// ---------------------------------------------------------------------------------------- 1.212 +template <typename TReal> 1.213 +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const 1.214 +{ 1.215 + aiMatrix4x4t<TReal> temp( *this); 1.216 + temp *= m; 1.217 + return temp; 1.218 +} 1.219 + 1.220 + 1.221 +// ---------------------------------------------------------------------------------------- 1.222 +template <typename TReal> 1.223 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() 1.224 +{ 1.225 + // (TReal&) don't remove, GCC complains cause of packed fields 1.226 + std::swap( (TReal&)b1, (TReal&)a2); 1.227 + std::swap( (TReal&)c1, (TReal&)a3); 1.228 + std::swap( (TReal&)c2, (TReal&)b3); 1.229 + std::swap( (TReal&)d1, (TReal&)a4); 1.230 + std::swap( (TReal&)d2, (TReal&)b4); 1.231 + std::swap( (TReal&)d3, (TReal&)c4); 1.232 + return *this; 1.233 +} 1.234 + 1.235 + 1.236 +// ---------------------------------------------------------------------------------------- 1.237 +template <typename TReal> 1.238 +inline TReal aiMatrix4x4t<TReal>::Determinant() const 1.239 +{ 1.240 + return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 1.241 + + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 1.242 + - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 1.243 + + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 1.244 + + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2 1.245 + - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1; 1.246 +} 1.247 + 1.248 +// ---------------------------------------------------------------------------------------- 1.249 +template <typename TReal> 1.250 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() 1.251 +{ 1.252 + // Compute the reciprocal determinant 1.253 + const TReal det = Determinant(); 1.254 + if(det == static_cast<TReal>(0.0)) 1.255 + { 1.256 + // Matrix not invertible. Setting all elements to nan is not really 1.257 + // correct in a mathematical sense but it is easy to debug for the 1.258 + // programmer. 1.259 + const TReal nan = std::numeric_limits<TReal>::quiet_NaN(); 1.260 + *this = aiMatrix4x4t<TReal>( 1.261 + nan,nan,nan,nan, 1.262 + nan,nan,nan,nan, 1.263 + nan,nan,nan,nan, 1.264 + nan,nan,nan,nan); 1.265 + 1.266 + return *this; 1.267 + } 1.268 + 1.269 + const TReal invdet = static_cast<TReal>(1.0) / det; 1.270 + 1.271 + aiMatrix4x4t<TReal> res; 1.272 + res.a1 = invdet * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2)); 1.273 + res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2)); 1.274 + res.a3 = invdet * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2)); 1.275 + res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2)); 1.276 + res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1)); 1.277 + res.b2 = invdet * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1)); 1.278 + res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1)); 1.279 + res.b4 = invdet * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1)); 1.280 + res.c1 = invdet * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1)); 1.281 + res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1)); 1.282 + res.c3 = invdet * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1)); 1.283 + res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1)); 1.284 + res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1)); 1.285 + res.d2 = invdet * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1)); 1.286 + res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1)); 1.287 + res.d4 = invdet * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); 1.288 + *this = res; 1.289 + 1.290 + return *this; 1.291 +} 1.292 + 1.293 +// ---------------------------------------------------------------------------------------- 1.294 +template <typename TReal> 1.295 +inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { 1.296 + if (p_iIndex > 3) { 1.297 + return NULL; 1.298 + } 1.299 + switch ( p_iIndex ) { 1.300 + case 0: 1.301 + return &a1; 1.302 + case 1: 1.303 + return &b1; 1.304 + case 2: 1.305 + return &c1; 1.306 + case 3: 1.307 + return &d1; 1.308 + default: 1.309 + break; 1.310 + } 1.311 + return &a1; 1.312 +} 1.313 + 1.314 +// ---------------------------------------------------------------------------------------- 1.315 +template <typename TReal> 1.316 +inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const { 1.317 + if (p_iIndex > 3) { 1.318 + return NULL; 1.319 + } 1.320 + 1.321 + switch ( p_iIndex ) { 1.322 + case 0: 1.323 + return &a1; 1.324 + case 1: 1.325 + return &b1; 1.326 + case 2: 1.327 + return &c1; 1.328 + case 3: 1.329 + return &d1; 1.330 + default: 1.331 + break; 1.332 + } 1.333 + return &a1; 1.334 +} 1.335 + 1.336 +// ---------------------------------------------------------------------------------------- 1.337 +template <typename TReal> 1.338 +inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const 1.339 +{ 1.340 + return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 && 1.341 + b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 && 1.342 + c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 && 1.343 + d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4); 1.344 +} 1.345 + 1.346 +// ---------------------------------------------------------------------------------------- 1.347 +template <typename TReal> 1.348 +inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const 1.349 +{ 1.350 + return !(*this == m); 1.351 +} 1.352 + 1.353 +// --------------------------------------------------------------------------- 1.354 +template<typename TReal> 1.355 +inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { 1.356 + return 1.357 + std::abs(a1 - m.a1) <= epsilon && 1.358 + std::abs(a2 - m.a2) <= epsilon && 1.359 + std::abs(a3 - m.a3) <= epsilon && 1.360 + std::abs(a4 - m.a4) <= epsilon && 1.361 + std::abs(b1 - m.b1) <= epsilon && 1.362 + std::abs(b2 - m.b2) <= epsilon && 1.363 + std::abs(b3 - m.b3) <= epsilon && 1.364 + std::abs(b4 - m.b4) <= epsilon && 1.365 + std::abs(c1 - m.c1) <= epsilon && 1.366 + std::abs(c2 - m.c2) <= epsilon && 1.367 + std::abs(c3 - m.c3) <= epsilon && 1.368 + std::abs(c4 - m.c4) <= epsilon && 1.369 + std::abs(d1 - m.d1) <= epsilon && 1.370 + std::abs(d2 - m.d2) <= epsilon && 1.371 + std::abs(d3 - m.d3) <= epsilon && 1.372 + std::abs(d4 - m.d4) <= epsilon; 1.373 +} 1.374 + 1.375 +// ---------------------------------------------------------------------------------------- 1.376 + 1.377 +#define ASSIMP_MATRIX4_4_DECOMPOSE_PART \ 1.378 + const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \ 1.379 + \ 1.380 + /* extract translation */ \ 1.381 + pPosition.x = _this[0][3]; \ 1.382 + pPosition.y = _this[1][3]; \ 1.383 + pPosition.z = _this[2][3]; \ 1.384 + \ 1.385 + /* extract the columns of the matrix. */ \ 1.386 + aiVector3t<TReal> vCols[3] = { \ 1.387 + aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \ 1.388 + aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \ 1.389 + aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \ 1.390 + }; \ 1.391 + \ 1.392 + /* extract the scaling factors */ \ 1.393 + pScaling.x = vCols[0].Length(); \ 1.394 + pScaling.y = vCols[1].Length(); \ 1.395 + pScaling.z = vCols[2].Length(); \ 1.396 + \ 1.397 + /* and the sign of the scaling */ \ 1.398 + if (Determinant() < 0) pScaling = -pScaling; \ 1.399 + \ 1.400 + /* and remove all scaling from the matrix */ \ 1.401 + if(pScaling.x) vCols[0] /= pScaling.x; \ 1.402 + if(pScaling.y) vCols[1] /= pScaling.y; \ 1.403 + if(pScaling.z) vCols[2] /= pScaling.z; \ 1.404 + \ 1.405 + do {} while(false) 1.406 + 1.407 + 1.408 + 1.409 + 1.410 +template <typename TReal> 1.411 +inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation, 1.412 + aiVector3t<TReal>& pPosition) const 1.413 +{ 1.414 + ASSIMP_MATRIX4_4_DECOMPOSE_PART; 1.415 + 1.416 + // build a 3x3 rotation matrix 1.417 + aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x, 1.418 + vCols[0].y,vCols[1].y,vCols[2].y, 1.419 + vCols[0].z,vCols[1].z,vCols[2].z); 1.420 + 1.421 + // and generate the rotation quaternion from it 1.422 + pRotation = aiQuaterniont<TReal>(m); 1.423 +} 1.424 + 1.425 +template <typename TReal> 1.426 +inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const 1.427 +{ 1.428 + ASSIMP_MATRIX4_4_DECOMPOSE_PART; 1.429 + 1.430 + /* 1.431 + assuming a right-handed coordinate system 1.432 + and post-multiplication of column vectors, 1.433 + the rotation matrix for an euler XYZ rotation is M = Rz * Ry * Rx. 1.434 + combining gives: 1.435 + 1.436 + | CE BDE-AF ADE+BF 0 | 1.437 + M = | CF BDF+AE ADF-BE 0 | 1.438 + | -D CB AC 0 | 1.439 + | 0 0 0 1 | 1.440 + 1.441 + where 1.442 + A = cos(angle_x), B = sin(angle_x); 1.443 + C = cos(angle_y), D = sin(angle_y); 1.444 + E = cos(angle_z), F = sin(angle_z); 1.445 + */ 1.446 + 1.447 + // Use a small epsilon to solve floating-point inaccuracies 1.448 + const TReal epsilon = 10e-3f; 1.449 + 1.450 + pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY. 1.451 + 1.452 + TReal C = std::cos(pRotation.y); 1.453 + 1.454 + if(std::fabs(C) > epsilon) 1.455 + { 1.456 + // Finding angle around oX. 1.457 + TReal tan_x = vCols[2].z / C;// A 1.458 + TReal tan_y = vCols[1].z / C;// B 1.459 + 1.460 + pRotation.x = std::atan2(tan_y, tan_x); 1.461 + // Finding angle around oZ. 1.462 + tan_x = vCols[0].x / C;// E 1.463 + tan_y = vCols[0].y / C;// F 1.464 + pRotation.z = std::atan2(tan_y, tan_x); 1.465 + } 1.466 + else 1.467 + {// oY is fixed. 1.468 + pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1. 1.469 + 1.470 + // And finding angle around oZ. 1.471 + TReal tan_x = vCols[1].y;// BDF+AE => E 1.472 + TReal tan_y = -vCols[1].x;// BDE-AF => F 1.473 + 1.474 + pRotation.z = std::atan2(tan_y, tan_x); 1.475 + } 1.476 +} 1.477 + 1.478 +#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART 1.479 + 1.480 +template <typename TReal> 1.481 +inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, 1.482 + aiVector3t<TReal>& pPosition) const 1.483 +{ 1.484 +aiQuaterniont<TReal> pRotation; 1.485 + 1.486 + Decompose(pScaling, pRotation, pPosition); 1.487 + pRotation.Normalize(); 1.488 + 1.489 + TReal angle_cos = pRotation.w; 1.490 + TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos); 1.491 + 1.492 + pRotationAngle = std::acos(angle_cos) * 2; 1.493 + 1.494 + // Use a small epsilon to solve floating-point inaccuracies 1.495 + const TReal epsilon = 10e-3f; 1.496 + 1.497 + if(std::fabs(angle_sin) < epsilon) angle_sin = 1; 1.498 + 1.499 + pRotationAxis.x = pRotation.x / angle_sin; 1.500 + pRotationAxis.y = pRotation.y / angle_sin; 1.501 + pRotationAxis.z = pRotation.z / angle_sin; 1.502 +} 1.503 + 1.504 +// ---------------------------------------------------------------------------------------- 1.505 +template <typename TReal> 1.506 +inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation, 1.507 + aiVector3t<TReal>& position) const 1.508 +{ 1.509 + const aiMatrix4x4t<TReal>& _this = *this; 1.510 + 1.511 + // extract translation 1.512 + position.x = _this[0][3]; 1.513 + position.y = _this[1][3]; 1.514 + position.z = _this[2][3]; 1.515 + 1.516 + // extract rotation 1.517 + rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this); 1.518 +} 1.519 + 1.520 +// ---------------------------------------------------------------------------------------- 1.521 +template <typename TReal> 1.522 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) 1.523 +{ 1.524 + return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z); 1.525 +} 1.526 + 1.527 +// ---------------------------------------------------------------------------------------- 1.528 +template <typename TReal> 1.529 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) 1.530 +{ 1.531 + aiMatrix4x4t<TReal>& _this = *this; 1.532 + 1.533 + TReal cx = std::cos(x); 1.534 + TReal sx = std::sin(x); 1.535 + TReal cy = std::cos(y); 1.536 + TReal sy = std::sin(y); 1.537 + TReal cz = std::cos(z); 1.538 + TReal sz = std::sin(z); 1.539 + 1.540 + // mz*my*mx 1.541 + _this.a1 = cz * cy; 1.542 + _this.a2 = cz * sy * sx - sz * cx; 1.543 + _this.a3 = sz * sx + cz * sy * cx; 1.544 + 1.545 + _this.b1 = sz * cy; 1.546 + _this.b2 = cz * cx + sz * sy * sx; 1.547 + _this.b3 = sz * sy * cx - cz * sx; 1.548 + 1.549 + _this.c1 = -sy; 1.550 + _this.c2 = cy * sx; 1.551 + _this.c3 = cy * cx; 1.552 + 1.553 + return *this; 1.554 +} 1.555 + 1.556 +// ---------------------------------------------------------------------------------------- 1.557 +template <typename TReal> 1.558 +inline bool aiMatrix4x4t<TReal>::IsIdentity() const 1.559 +{ 1.560 + // Use a small epsilon to solve floating-point inaccuracies 1.561 + const static TReal epsilon = 10e-3f; 1.562 + 1.563 + return (a2 <= epsilon && a2 >= -epsilon && 1.564 + a3 <= epsilon && a3 >= -epsilon && 1.565 + a4 <= epsilon && a4 >= -epsilon && 1.566 + b1 <= epsilon && b1 >= -epsilon && 1.567 + b3 <= epsilon && b3 >= -epsilon && 1.568 + b4 <= epsilon && b4 >= -epsilon && 1.569 + c1 <= epsilon && c1 >= -epsilon && 1.570 + c2 <= epsilon && c2 >= -epsilon && 1.571 + c4 <= epsilon && c4 >= -epsilon && 1.572 + d1 <= epsilon && d1 >= -epsilon && 1.573 + d2 <= epsilon && d2 >= -epsilon && 1.574 + d3 <= epsilon && d3 >= -epsilon && 1.575 + a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && 1.576 + b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && 1.577 + c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && 1.578 + d4 <= 1.f+epsilon && d4 >= 1.f-epsilon); 1.579 +} 1.580 + 1.581 +// ---------------------------------------------------------------------------------------- 1.582 +template <typename TReal> 1.583 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) 1.584 +{ 1.585 + /* 1.586 + | 1 0 0 0 | 1.587 + M = | 0 cos(A) -sin(A) 0 | 1.588 + | 0 sin(A) cos(A) 0 | 1.589 + | 0 0 0 1 | */ 1.590 + out = aiMatrix4x4t<TReal>(); 1.591 + out.b2 = out.c3 = std::cos(a); 1.592 + out.b3 = -(out.c2 = std::sin(a)); 1.593 + return out; 1.594 +} 1.595 + 1.596 +// ---------------------------------------------------------------------------------------- 1.597 +template <typename TReal> 1.598 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) 1.599 +{ 1.600 + /* 1.601 + | cos(A) 0 sin(A) 0 | 1.602 + M = | 0 1 0 0 | 1.603 + | -sin(A) 0 cos(A) 0 | 1.604 + | 0 0 0 1 | 1.605 + */ 1.606 + out = aiMatrix4x4t<TReal>(); 1.607 + out.a1 = out.c3 = std::cos(a); 1.608 + out.c1 = -(out.a3 = std::sin(a)); 1.609 + return out; 1.610 +} 1.611 + 1.612 +// ---------------------------------------------------------------------------------------- 1.613 +template <typename TReal> 1.614 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) 1.615 +{ 1.616 + /* 1.617 + | cos(A) -sin(A) 0 0 | 1.618 + M = | sin(A) cos(A) 0 0 | 1.619 + | 0 0 1 0 | 1.620 + | 0 0 0 1 | */ 1.621 + out = aiMatrix4x4t<TReal>(); 1.622 + out.a1 = out.b2 = std::cos(a); 1.623 + out.a2 = -(out.b1 = std::sin(a)); 1.624 + return out; 1.625 +} 1.626 + 1.627 +// ---------------------------------------------------------------------------------------- 1.628 +// Returns a rotation matrix for a rotation around an arbitrary axis. 1.629 +template <typename TReal> 1.630 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out) 1.631 +{ 1.632 + TReal c = std::cos( a), s = std::sin( a), t = 1 - c; 1.633 + TReal x = axis.x, y = axis.y, z = axis.z; 1.634 + 1.635 + // Many thanks to MathWorld and Wikipedia 1.636 + out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y; 1.637 + out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x; 1.638 + out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c; 1.639 + out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0); 1.640 + out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0); 1.641 + out.d4 = static_cast<TReal>(1.0); 1.642 + 1.643 + return out; 1.644 +} 1.645 + 1.646 +// ---------------------------------------------------------------------------------------- 1.647 +template <typename TReal> 1.648 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) 1.649 +{ 1.650 + out = aiMatrix4x4t<TReal>(); 1.651 + out.a4 = v.x; 1.652 + out.b4 = v.y; 1.653 + out.c4 = v.z; 1.654 + return out; 1.655 +} 1.656 + 1.657 +// ---------------------------------------------------------------------------------------- 1.658 +template <typename TReal> 1.659 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) 1.660 +{ 1.661 + out = aiMatrix4x4t<TReal>(); 1.662 + out.a1 = v.x; 1.663 + out.b2 = v.y; 1.664 + out.c3 = v.z; 1.665 + return out; 1.666 +} 1.667 + 1.668 +// ---------------------------------------------------------------------------------------- 1.669 +/** A function for creating a rotation matrix that rotates a vector called 1.670 + * "from" into another vector called "to". 1.671 + * Input : from[3], to[3] which both must be *normalized* non-zero vectors 1.672 + * Output: mtx[3][3] -- a 3x3 matrix in colum-major form 1.673 + * Authors: Tomas Möller, John Hughes 1.674 + * "Efficiently Building a Matrix to Rotate One Vector to Another" 1.675 + * Journal of Graphics Tools, 4(4):1-4, 1999 1.676 + */ 1.677 +// ---------------------------------------------------------------------------------------- 1.678 +template <typename TReal> 1.679 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, 1.680 + const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) 1.681 +{ 1.682 + aiMatrix3x3t<TReal> m3; 1.683 + aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3); 1.684 + mtx = aiMatrix4x4t<TReal>(m3); 1.685 + return mtx; 1.686 +} 1.687 + 1.688 +#endif // __cplusplus 1.689 +#endif // AI_MATRIX4X4_INL_INC