vrshoot

annotate libs/assimp/assimp/matrix4x4.inl @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 /** @file aiMatrix4x4t<TReal>.inl
nuclear@0 43 * @brief Inline implementation of the 4x4 matrix operators
nuclear@0 44 */
nuclear@0 45 #ifndef AI_MATRIX4x4_INL_INC
nuclear@0 46 #define AI_MATRIX4x4_INL_INC
nuclear@0 47
nuclear@0 48 #ifdef __cplusplus
nuclear@0 49
nuclear@0 50 #include "matrix4x4.h"
nuclear@0 51 #include "matrix3x3.h"
nuclear@0 52 #include "quaternion.h"
nuclear@0 53
nuclear@0 54 #include <algorithm>
nuclear@0 55 #include <limits>
nuclear@0 56 #include <math.h>
nuclear@0 57
nuclear@0 58 // ----------------------------------------------------------------------------------------
nuclear@0 59 template <typename TReal>
nuclear@0 60 aiMatrix4x4t<TReal> ::aiMatrix4x4t () :
nuclear@0 61 a1(1.0f), a2(), a3(), a4(),
nuclear@0 62 b1(), b2(1.0f), b3(), b4(),
nuclear@0 63 c1(), c2(), c3(1.0f), c4(),
nuclear@0 64 d1(), d2(), d3(), d4(1.0f)
nuclear@0 65 {
nuclear@0 66
nuclear@0 67 }
nuclear@0 68
nuclear@0 69 // ----------------------------------------------------------------------------------------
nuclear@0 70 template <typename TReal>
nuclear@0 71 aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
nuclear@0 72 TReal _b1, TReal _b2, TReal _b3, TReal _b4,
nuclear@0 73 TReal _c1, TReal _c2, TReal _c3, TReal _c4,
nuclear@0 74 TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
nuclear@0 75 a1(_a1), a2(_a2), a3(_a3), a4(_a4),
nuclear@0 76 b1(_b1), b2(_b2), b3(_b3), b4(_b4),
nuclear@0 77 c1(_c1), c2(_c2), c3(_c3), c4(_c4),
nuclear@0 78 d1(_d1), d2(_d2), d3(_d3), d4(_d4)
nuclear@0 79 {
nuclear@0 80
nuclear@0 81 }
nuclear@0 82
nuclear@0 83 // ------------------------------------------------------------------------------------------------
nuclear@0 84 template <typename TReal>
nuclear@0 85 template <typename TOther>
nuclear@0 86 aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
nuclear@0 87 {
nuclear@0 88 return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
nuclear@0 89 static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
nuclear@0 90 static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
nuclear@0 91 static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
nuclear@0 92 }
nuclear@0 93
nuclear@0 94
nuclear@0 95 // ----------------------------------------------------------------------------------------
nuclear@0 96 template <typename TReal>
nuclear@0 97 inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
nuclear@0 98 {
nuclear@0 99 a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
nuclear@0 100 b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
nuclear@0 101 c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
nuclear@0 102 d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
nuclear@0 103 }
nuclear@0 104
nuclear@0 105 // ----------------------------------------------------------------------------------------
nuclear@0 106 template <typename TReal>
nuclear@0 107 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
nuclear@0 108 {
nuclear@0 109 *this = aiMatrix4x4t<TReal>(
nuclear@0 110 m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
nuclear@0 111 m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
nuclear@0 112 m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
nuclear@0 113 m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
nuclear@0 114 m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
nuclear@0 115 m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
nuclear@0 116 m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
nuclear@0 117 m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
nuclear@0 118 m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
nuclear@0 119 m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
nuclear@0 120 m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
nuclear@0 121 m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
nuclear@0 122 m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
nuclear@0 123 m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
nuclear@0 124 m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
nuclear@0 125 m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
nuclear@0 126 return *this;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 // ----------------------------------------------------------------------------------------
nuclear@0 130 template <typename TReal>
nuclear@0 131 inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
nuclear@0 132 {
nuclear@0 133 aiMatrix4x4t<TReal> temp( *this);
nuclear@0 134 temp *= m;
nuclear@0 135 return temp;
nuclear@0 136 }
nuclear@0 137
nuclear@0 138
nuclear@0 139 // ----------------------------------------------------------------------------------------
nuclear@0 140 template <typename TReal>
nuclear@0 141 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
nuclear@0 142 {
nuclear@0 143 // (TReal&) don't remove, GCC complains cause of packed fields
nuclear@0 144 std::swap( (TReal&)b1, (TReal&)a2);
nuclear@0 145 std::swap( (TReal&)c1, (TReal&)a3);
nuclear@0 146 std::swap( (TReal&)c2, (TReal&)b3);
nuclear@0 147 std::swap( (TReal&)d1, (TReal&)a4);
nuclear@0 148 std::swap( (TReal&)d2, (TReal&)b4);
nuclear@0 149 std::swap( (TReal&)d3, (TReal&)c4);
nuclear@0 150 return *this;
nuclear@0 151 }
nuclear@0 152
nuclear@0 153
nuclear@0 154 // ----------------------------------------------------------------------------------------
nuclear@0 155 template <typename TReal>
nuclear@0 156 inline TReal aiMatrix4x4t<TReal>::Determinant() const
nuclear@0 157 {
nuclear@0 158 return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
nuclear@0 159 + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
nuclear@0 160 - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3
nuclear@0 161 + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2
nuclear@0 162 + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2
nuclear@0 163 - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1;
nuclear@0 164 }
nuclear@0 165
nuclear@0 166 // ----------------------------------------------------------------------------------------
nuclear@0 167 template <typename TReal>
nuclear@0 168 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
nuclear@0 169 {
nuclear@0 170 // Compute the reciprocal determinant
nuclear@0 171 const TReal det = Determinant();
nuclear@0 172 if(det == static_cast<TReal>(0.0))
nuclear@0 173 {
nuclear@0 174 // Matrix not invertible. Setting all elements to nan is not really
nuclear@0 175 // correct in a mathematical sense but it is easy to debug for the
nuclear@0 176 // programmer.
nuclear@0 177 const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
nuclear@0 178 *this = aiMatrix4x4t<TReal>(
nuclear@0 179 nan,nan,nan,nan,
nuclear@0 180 nan,nan,nan,nan,
nuclear@0 181 nan,nan,nan,nan,
nuclear@0 182 nan,nan,nan,nan);
nuclear@0 183
nuclear@0 184 return *this;
nuclear@0 185 }
nuclear@0 186
nuclear@0 187 const TReal invdet = static_cast<TReal>(1.0) / det;
nuclear@0 188
nuclear@0 189 aiMatrix4x4t<TReal> res;
nuclear@0 190 res.a1 = invdet * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
nuclear@0 191 res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
nuclear@0 192 res.a3 = invdet * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
nuclear@0 193 res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
nuclear@0 194 res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
nuclear@0 195 res.b2 = invdet * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
nuclear@0 196 res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
nuclear@0 197 res.b4 = invdet * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
nuclear@0 198 res.c1 = invdet * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
nuclear@0 199 res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
nuclear@0 200 res.c3 = invdet * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
nuclear@0 201 res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
nuclear@0 202 res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1));
nuclear@0 203 res.d2 = invdet * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1));
nuclear@0 204 res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1));
nuclear@0 205 res.d4 = invdet * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1));
nuclear@0 206 *this = res;
nuclear@0 207
nuclear@0 208 return *this;
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 // ----------------------------------------------------------------------------------------
nuclear@0 212 template <typename TReal>
nuclear@0 213 inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex)
nuclear@0 214 {
nuclear@0 215 // XXX this is UB. Has been for years. The fact that it works now does not make it better.
nuclear@0 216 return &this->a1 + p_iIndex * 4;
nuclear@0 217 }
nuclear@0 218
nuclear@0 219 // ----------------------------------------------------------------------------------------
nuclear@0 220 template <typename TReal>
nuclear@0 221 inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
nuclear@0 222 {
nuclear@0 223 // XXX same
nuclear@0 224 return &this->a1 + p_iIndex * 4;
nuclear@0 225 }
nuclear@0 226
nuclear@0 227 // ----------------------------------------------------------------------------------------
nuclear@0 228 template <typename TReal>
nuclear@0 229 inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
nuclear@0 230 {
nuclear@0 231 return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
nuclear@0 232 b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
nuclear@0 233 c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
nuclear@0 234 d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
nuclear@0 235 }
nuclear@0 236
nuclear@0 237 // ----------------------------------------------------------------------------------------
nuclear@0 238 template <typename TReal>
nuclear@0 239 inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
nuclear@0 240 {
nuclear@0 241 return !(*this == m);
nuclear@0 242 }
nuclear@0 243
nuclear@0 244 // ----------------------------------------------------------------------------------------
nuclear@0 245 template <typename TReal>
nuclear@0 246 inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
nuclear@0 247 aiVector3t<TReal>& position) const
nuclear@0 248 {
nuclear@0 249 const aiMatrix4x4t<TReal>& _this = *this;
nuclear@0 250
nuclear@0 251 // extract translation
nuclear@0 252 position.x = _this[0][3];
nuclear@0 253 position.y = _this[1][3];
nuclear@0 254 position.z = _this[2][3];
nuclear@0 255
nuclear@0 256 // extract the rows of the matrix
nuclear@0 257 aiVector3t<TReal> vRows[3] = {
nuclear@0 258 aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
nuclear@0 259 aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
nuclear@0 260 aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
nuclear@0 261 };
nuclear@0 262
nuclear@0 263 // extract the scaling factors
nuclear@0 264 scaling.x = vRows[0].Length();
nuclear@0 265 scaling.y = vRows[1].Length();
nuclear@0 266 scaling.z = vRows[2].Length();
nuclear@0 267
nuclear@0 268 // and the sign of the scaling
nuclear@0 269 if (Determinant() < 0) {
nuclear@0 270 scaling.x = -scaling.x;
nuclear@0 271 scaling.y = -scaling.y;
nuclear@0 272 scaling.z = -scaling.z;
nuclear@0 273 }
nuclear@0 274
nuclear@0 275 // and remove all scaling from the matrix
nuclear@0 276 if(scaling.x)
nuclear@0 277 {
nuclear@0 278 vRows[0] /= scaling.x;
nuclear@0 279 }
nuclear@0 280 if(scaling.y)
nuclear@0 281 {
nuclear@0 282 vRows[1] /= scaling.y;
nuclear@0 283 }
nuclear@0 284 if(scaling.z)
nuclear@0 285 {
nuclear@0 286 vRows[2] /= scaling.z;
nuclear@0 287 }
nuclear@0 288
nuclear@0 289 // build a 3x3 rotation matrix
nuclear@0 290 aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
nuclear@0 291 vRows[0].y,vRows[1].y,vRows[2].y,
nuclear@0 292 vRows[0].z,vRows[1].z,vRows[2].z);
nuclear@0 293
nuclear@0 294 // and generate the rotation quaternion from it
nuclear@0 295 rotation = aiQuaterniont<TReal>(m);
nuclear@0 296 }
nuclear@0 297
nuclear@0 298 // ----------------------------------------------------------------------------------------
nuclear@0 299 template <typename TReal>
nuclear@0 300 inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
nuclear@0 301 aiVector3t<TReal>& position) const
nuclear@0 302 {
nuclear@0 303 const aiMatrix4x4t<TReal>& _this = *this;
nuclear@0 304
nuclear@0 305 // extract translation
nuclear@0 306 position.x = _this[0][3];
nuclear@0 307 position.y = _this[1][3];
nuclear@0 308 position.z = _this[2][3];
nuclear@0 309
nuclear@0 310 // extract rotation
nuclear@0 311 rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
nuclear@0 312 }
nuclear@0 313
nuclear@0 314 // ----------------------------------------------------------------------------------------
nuclear@0 315 template <typename TReal>
nuclear@0 316 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
nuclear@0 317 {
nuclear@0 318 return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
nuclear@0 319 }
nuclear@0 320
nuclear@0 321 // ----------------------------------------------------------------------------------------
nuclear@0 322 template <typename TReal>
nuclear@0 323 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
nuclear@0 324 {
nuclear@0 325 aiMatrix4x4t<TReal>& _this = *this;
nuclear@0 326
nuclear@0 327 TReal cr = cos( x );
nuclear@0 328 TReal sr = sin( x );
nuclear@0 329 TReal cp = cos( y );
nuclear@0 330 TReal sp = sin( y );
nuclear@0 331 TReal cy = cos( z );
nuclear@0 332 TReal sy = sin( z );
nuclear@0 333
nuclear@0 334 _this.a1 = cp*cy ;
nuclear@0 335 _this.a2 = cp*sy;
nuclear@0 336 _this.a3 = -sp ;
nuclear@0 337
nuclear@0 338 TReal srsp = sr*sp;
nuclear@0 339 TReal crsp = cr*sp;
nuclear@0 340
nuclear@0 341 _this.b1 = srsp*cy-cr*sy ;
nuclear@0 342 _this.b2 = srsp*sy+cr*cy ;
nuclear@0 343 _this.b3 = sr*cp ;
nuclear@0 344
nuclear@0 345 _this.c1 = crsp*cy+sr*sy ;
nuclear@0 346 _this.c2 = crsp*sy-sr*cy ;
nuclear@0 347 _this.c3 = cr*cp ;
nuclear@0 348
nuclear@0 349 return *this;
nuclear@0 350 }
nuclear@0 351
nuclear@0 352 // ----------------------------------------------------------------------------------------
nuclear@0 353 template <typename TReal>
nuclear@0 354 inline bool aiMatrix4x4t<TReal>::IsIdentity() const
nuclear@0 355 {
nuclear@0 356 // Use a small epsilon to solve floating-point inaccuracies
nuclear@0 357 const static TReal epsilon = 10e-3f;
nuclear@0 358
nuclear@0 359 return (a2 <= epsilon && a2 >= -epsilon &&
nuclear@0 360 a3 <= epsilon && a3 >= -epsilon &&
nuclear@0 361 a4 <= epsilon && a4 >= -epsilon &&
nuclear@0 362 b1 <= epsilon && b1 >= -epsilon &&
nuclear@0 363 b3 <= epsilon && b3 >= -epsilon &&
nuclear@0 364 b4 <= epsilon && b4 >= -epsilon &&
nuclear@0 365 c1 <= epsilon && c1 >= -epsilon &&
nuclear@0 366 c2 <= epsilon && c2 >= -epsilon &&
nuclear@0 367 c4 <= epsilon && c4 >= -epsilon &&
nuclear@0 368 d1 <= epsilon && d1 >= -epsilon &&
nuclear@0 369 d2 <= epsilon && d2 >= -epsilon &&
nuclear@0 370 d3 <= epsilon && d3 >= -epsilon &&
nuclear@0 371 a1 <= 1.f+epsilon && a1 >= 1.f-epsilon &&
nuclear@0 372 b2 <= 1.f+epsilon && b2 >= 1.f-epsilon &&
nuclear@0 373 c3 <= 1.f+epsilon && c3 >= 1.f-epsilon &&
nuclear@0 374 d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
nuclear@0 375 }
nuclear@0 376
nuclear@0 377 // ----------------------------------------------------------------------------------------
nuclear@0 378 template <typename TReal>
nuclear@0 379 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
nuclear@0 380 {
nuclear@0 381 /*
nuclear@0 382 | 1 0 0 0 |
nuclear@0 383 M = | 0 cos(A) -sin(A) 0 |
nuclear@0 384 | 0 sin(A) cos(A) 0 |
nuclear@0 385 | 0 0 0 1 | */
nuclear@0 386 out = aiMatrix4x4t<TReal>();
nuclear@0 387 out.b2 = out.c3 = cos(a);
nuclear@0 388 out.b3 = -(out.c2 = sin(a));
nuclear@0 389 return out;
nuclear@0 390 }
nuclear@0 391
nuclear@0 392 // ----------------------------------------------------------------------------------------
nuclear@0 393 template <typename TReal>
nuclear@0 394 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
nuclear@0 395 {
nuclear@0 396 /*
nuclear@0 397 | cos(A) 0 sin(A) 0 |
nuclear@0 398 M = | 0 1 0 0 |
nuclear@0 399 | -sin(A) 0 cos(A) 0 |
nuclear@0 400 | 0 0 0 1 |
nuclear@0 401 */
nuclear@0 402 out = aiMatrix4x4t<TReal>();
nuclear@0 403 out.a1 = out.c3 = cos(a);
nuclear@0 404 out.c1 = -(out.a3 = sin(a));
nuclear@0 405 return out;
nuclear@0 406 }
nuclear@0 407
nuclear@0 408 // ----------------------------------------------------------------------------------------
nuclear@0 409 template <typename TReal>
nuclear@0 410 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
nuclear@0 411 {
nuclear@0 412 /*
nuclear@0 413 | cos(A) -sin(A) 0 0 |
nuclear@0 414 M = | sin(A) cos(A) 0 0 |
nuclear@0 415 | 0 0 1 0 |
nuclear@0 416 | 0 0 0 1 | */
nuclear@0 417 out = aiMatrix4x4t<TReal>();
nuclear@0 418 out.a1 = out.b2 = cos(a);
nuclear@0 419 out.a2 = -(out.b1 = sin(a));
nuclear@0 420 return out;
nuclear@0 421 }
nuclear@0 422
nuclear@0 423 // ----------------------------------------------------------------------------------------
nuclear@0 424 // Returns a rotation matrix for a rotation around an arbitrary axis.
nuclear@0 425 template <typename TReal>
nuclear@0 426 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
nuclear@0 427 {
nuclear@0 428 TReal c = cos( a), s = sin( a), t = 1 - c;
nuclear@0 429 TReal x = axis.x, y = axis.y, z = axis.z;
nuclear@0 430
nuclear@0 431 // Many thanks to MathWorld and Wikipedia
nuclear@0 432 out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
nuclear@0 433 out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
nuclear@0 434 out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
nuclear@0 435 out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
nuclear@0 436 out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
nuclear@0 437 out.d4 = static_cast<TReal>(1.0);
nuclear@0 438
nuclear@0 439 return out;
nuclear@0 440 }
nuclear@0 441
nuclear@0 442 // ----------------------------------------------------------------------------------------
nuclear@0 443 template <typename TReal>
nuclear@0 444 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
nuclear@0 445 {
nuclear@0 446 out = aiMatrix4x4t<TReal>();
nuclear@0 447 out.a4 = v.x;
nuclear@0 448 out.b4 = v.y;
nuclear@0 449 out.c4 = v.z;
nuclear@0 450 return out;
nuclear@0 451 }
nuclear@0 452
nuclear@0 453 // ----------------------------------------------------------------------------------------
nuclear@0 454 template <typename TReal>
nuclear@0 455 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
nuclear@0 456 {
nuclear@0 457 out = aiMatrix4x4t<TReal>();
nuclear@0 458 out.a1 = v.x;
nuclear@0 459 out.b2 = v.y;
nuclear@0 460 out.c3 = v.z;
nuclear@0 461 return out;
nuclear@0 462 }
nuclear@0 463
nuclear@0 464 // ----------------------------------------------------------------------------------------
nuclear@0 465 /** A function for creating a rotation matrix that rotates a vector called
nuclear@0 466 * "from" into another vector called "to".
nuclear@0 467 * Input : from[3], to[3] which both must be *normalized* non-zero vectors
nuclear@0 468 * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
nuclear@0 469 * Authors: Tomas Möller, John Hughes
nuclear@0 470 * "Efficiently Building a Matrix to Rotate One Vector to Another"
nuclear@0 471 * Journal of Graphics Tools, 4(4):1-4, 1999
nuclear@0 472 */
nuclear@0 473 // ----------------------------------------------------------------------------------------
nuclear@0 474 template <typename TReal>
nuclear@0 475 inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
nuclear@0 476 const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
nuclear@0 477 {
nuclear@0 478 aiMatrix3x3t<TReal> m3;
nuclear@0 479 aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
nuclear@0 480 mtx = aiMatrix4x4t<TReal>(m3);
nuclear@0 481 return mtx;
nuclear@0 482 }
nuclear@0 483
nuclear@0 484 #endif // __cplusplus
nuclear@0 485 #endif // AI_MATRIX4x4_INL_INC