vrshoot

diff 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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/assimp/matrix4x4.inl	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,485 @@
     1.4 +/*
     1.5 +---------------------------------------------------------------------------
     1.6 +Open Asset Import Library (assimp)
     1.7 +---------------------------------------------------------------------------
     1.8 +
     1.9 +Copyright (c) 2006-2012, assimp team
    1.10 +
    1.11 +All rights reserved.
    1.12 +
    1.13 +Redistribution and use of this software in source and binary forms, 
    1.14 +with or without modification, are permitted provided that the following 
    1.15 +conditions are met:
    1.16 +
    1.17 +* Redistributions of source code must retain the above
    1.18 +  copyright notice, this list of conditions and the
    1.19 +  following disclaimer.
    1.20 +
    1.21 +* Redistributions in binary form must reproduce the above
    1.22 +  copyright notice, this list of conditions and the
    1.23 +  following disclaimer in the documentation and/or other
    1.24 +  materials provided with the distribution.
    1.25 +
    1.26 +* Neither the name of the assimp team, nor the names of its
    1.27 +  contributors may be used to endorse or promote products
    1.28 +  derived from this software without specific prior
    1.29 +  written permission of the assimp team.
    1.30 +
    1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
    1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.42 +---------------------------------------------------------------------------
    1.43 +*/
    1.44 +
    1.45 +/** @file aiMatrix4x4t<TReal>.inl
    1.46 + *  @brief Inline implementation of the 4x4 matrix operators
    1.47 + */
    1.48 +#ifndef AI_MATRIX4x4_INL_INC
    1.49 +#define AI_MATRIX4x4_INL_INC
    1.50 +
    1.51 +#ifdef __cplusplus
    1.52 +
    1.53 +#include "matrix4x4.h"
    1.54 +#include "matrix3x3.h"
    1.55 +#include "quaternion.h"
    1.56 +
    1.57 +#include <algorithm>
    1.58 +#include <limits>
    1.59 +#include <math.h>
    1.60 +
    1.61 +// ----------------------------------------------------------------------------------------
    1.62 +template <typename TReal>
    1.63 +aiMatrix4x4t<TReal> ::aiMatrix4x4t () :	
    1.64 +	a1(1.0f), a2(), a3(), a4(), 
    1.65 +	b1(), b2(1.0f), b3(), b4(), 
    1.66 +	c1(), c2(), c3(1.0f), c4(),
    1.67 +	d1(), d2(), d3(), d4(1.0f)
    1.68 +{
    1.69 +
    1.70 +}
    1.71 +
    1.72 +// ----------------------------------------------------------------------------------------
    1.73 +template <typename TReal>
    1.74 +aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
    1.75 +			  TReal _b1, TReal _b2, TReal _b3, TReal _b4,
    1.76 +			  TReal _c1, TReal _c2, TReal _c3, TReal _c4,
    1.77 +			  TReal _d1, TReal _d2, TReal _d3, TReal _d4) :	
    1.78 +	a1(_a1), a2(_a2), a3(_a3), a4(_a4),  
    1.79 +	b1(_b1), b2(_b2), b3(_b3), b4(_b4), 
    1.80 +	c1(_c1), c2(_c2), c3(_c3), c4(_c4),
    1.81 +	d1(_d1), d2(_d2), d3(_d3), d4(_d4)
    1.82 +{
    1.83 +	
    1.84 +}
    1.85 +
    1.86 +// ------------------------------------------------------------------------------------------------
    1.87 +template <typename TReal>
    1.88 +template <typename TOther>
    1.89 +aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
    1.90 +{
    1.91 +	return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
    1.92 +		static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
    1.93 +		static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
    1.94 +		static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
    1.95 +}
    1.96 +
    1.97 +
    1.98 +// ----------------------------------------------------------------------------------------
    1.99 +template <typename TReal>
   1.100 +inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
   1.101 +{
   1.102 +	a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
   1.103 +	b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
   1.104 +	c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
   1.105 +	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.106 +}
   1.107 +
   1.108 +// ----------------------------------------------------------------------------------------
   1.109 +template <typename TReal>
   1.110 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
   1.111 +{
   1.112 +	*this = aiMatrix4x4t<TReal>(
   1.113 +		m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
   1.114 +		m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
   1.115 +		m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
   1.116 +		m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
   1.117 +		m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
   1.118 +		m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
   1.119 +		m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
   1.120 +		m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
   1.121 +		m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
   1.122 +		m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
   1.123 +		m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
   1.124 +		m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
   1.125 +		m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
   1.126 +		m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
   1.127 +		m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
   1.128 +		m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
   1.129 +	return *this;
   1.130 +}
   1.131 +
   1.132 +// ----------------------------------------------------------------------------------------
   1.133 +template <typename TReal>
   1.134 +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
   1.135 +{
   1.136 +	aiMatrix4x4t<TReal> temp( *this);
   1.137 +	temp *= m;
   1.138 +	return temp;
   1.139 +}
   1.140 +
   1.141 +
   1.142 +// ----------------------------------------------------------------------------------------
   1.143 +template <typename TReal>
   1.144 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
   1.145 +{
   1.146 +	// (TReal&) don't remove, GCC complains cause of packed fields
   1.147 +	std::swap( (TReal&)b1, (TReal&)a2);
   1.148 +	std::swap( (TReal&)c1, (TReal&)a3);
   1.149 +	std::swap( (TReal&)c2, (TReal&)b3);
   1.150 +	std::swap( (TReal&)d1, (TReal&)a4);
   1.151 +	std::swap( (TReal&)d2, (TReal&)b4);
   1.152 +	std::swap( (TReal&)d3, (TReal&)c4);
   1.153 +	return *this;
   1.154 +}
   1.155 +
   1.156 +
   1.157 +// ----------------------------------------------------------------------------------------
   1.158 +template <typename TReal>
   1.159 +inline TReal aiMatrix4x4t<TReal>::Determinant() const
   1.160 +{
   1.161 +	return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 
   1.162 +		+ a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 
   1.163 +		- a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 
   1.164 +		+ a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 
   1.165 +		+ a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2
   1.166 +		- a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1;
   1.167 +}
   1.168 +
   1.169 +// ----------------------------------------------------------------------------------------
   1.170 +template <typename TReal>
   1.171 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
   1.172 +{
   1.173 +	// Compute the reciprocal determinant
   1.174 +	const TReal det = Determinant();
   1.175 +	if(det == static_cast<TReal>(0.0)) 
   1.176 +	{
   1.177 +		// Matrix not invertible. Setting all elements to nan is not really
   1.178 +		// correct in a mathematical sense but it is easy to debug for the
   1.179 +		// programmer.
   1.180 +		const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
   1.181 +		*this = aiMatrix4x4t<TReal>(
   1.182 +			nan,nan,nan,nan,
   1.183 +			nan,nan,nan,nan,
   1.184 +			nan,nan,nan,nan,
   1.185 +			nan,nan,nan,nan);
   1.186 +
   1.187 +		return *this;
   1.188 +	}
   1.189 +
   1.190 +	const TReal invdet = static_cast<TReal>(1.0) / det;
   1.191 +
   1.192 +	aiMatrix4x4t<TReal> res;
   1.193 +	res.a1 = invdet  * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
   1.194 +	res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
   1.195 +	res.a3 = invdet  * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
   1.196 +	res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
   1.197 +	res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
   1.198 +	res.b2 = invdet  * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
   1.199 +	res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
   1.200 +	res.b4 = invdet  * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
   1.201 +	res.c1 = invdet  * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
   1.202 +	res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
   1.203 +	res.c3 = invdet  * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
   1.204 +	res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
   1.205 +	res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1));
   1.206 +	res.d2 = invdet  * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1));
   1.207 +	res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1));
   1.208 +	res.d4 = invdet  * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); 
   1.209 +	*this = res;
   1.210 +
   1.211 +	return *this;
   1.212 +}
   1.213 +
   1.214 +// ----------------------------------------------------------------------------------------
   1.215 +template <typename TReal>
   1.216 +inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex)
   1.217 +{
   1.218 +	// XXX this is UB. Has been for years. The fact that it works now does not make it better.
   1.219 +	return &this->a1 + p_iIndex * 4;
   1.220 +}
   1.221 +
   1.222 +// ----------------------------------------------------------------------------------------
   1.223 +template <typename TReal>
   1.224 +inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
   1.225 +{
   1.226 +	// XXX same
   1.227 +	return &this->a1 + p_iIndex * 4;
   1.228 +}
   1.229 +
   1.230 +// ----------------------------------------------------------------------------------------
   1.231 +template <typename TReal>
   1.232 +inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
   1.233 +{
   1.234 +	return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
   1.235 +			b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
   1.236 +			c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
   1.237 +			d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
   1.238 +}
   1.239 +
   1.240 +// ----------------------------------------------------------------------------------------
   1.241 +template <typename TReal>
   1.242 +inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
   1.243 +{
   1.244 +	return !(*this == m);
   1.245 +}
   1.246 +
   1.247 +// ----------------------------------------------------------------------------------------
   1.248 +template <typename TReal>
   1.249 +inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
   1.250 +	aiVector3t<TReal>& position) const
   1.251 +{
   1.252 +	const aiMatrix4x4t<TReal>& _this = *this;
   1.253 +
   1.254 +	// extract translation
   1.255 +	position.x = _this[0][3];
   1.256 +	position.y = _this[1][3];
   1.257 +	position.z = _this[2][3];
   1.258 +
   1.259 +	// extract the rows of the matrix
   1.260 +	aiVector3t<TReal> vRows[3] = {
   1.261 +		aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
   1.262 +		aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
   1.263 +		aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
   1.264 +	};
   1.265 +
   1.266 +	// extract the scaling factors
   1.267 +	scaling.x = vRows[0].Length();
   1.268 +	scaling.y = vRows[1].Length();
   1.269 +	scaling.z = vRows[2].Length();
   1.270 +
   1.271 +	// and the sign of the scaling
   1.272 +	if (Determinant() < 0) {
   1.273 +		scaling.x = -scaling.x;
   1.274 +		scaling.y = -scaling.y;
   1.275 +		scaling.z = -scaling.z;
   1.276 +	}
   1.277 +
   1.278 +	// and remove all scaling from the matrix
   1.279 +	if(scaling.x)
   1.280 +	{
   1.281 +		vRows[0] /= scaling.x;
   1.282 +	}
   1.283 +	if(scaling.y)
   1.284 +	{
   1.285 +		vRows[1] /= scaling.y;
   1.286 +	}
   1.287 +	if(scaling.z)
   1.288 +	{
   1.289 +		vRows[2] /= scaling.z;
   1.290 +	}
   1.291 +
   1.292 +	// build a 3x3 rotation matrix
   1.293 +	aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
   1.294 +		vRows[0].y,vRows[1].y,vRows[2].y,
   1.295 +		vRows[0].z,vRows[1].z,vRows[2].z);
   1.296 +
   1.297 +	// and generate the rotation quaternion from it
   1.298 +	rotation = aiQuaterniont<TReal>(m);
   1.299 +}
   1.300 +
   1.301 +// ----------------------------------------------------------------------------------------
   1.302 +template <typename TReal>
   1.303 +inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
   1.304 +	aiVector3t<TReal>& position) const
   1.305 +{
   1.306 +	const aiMatrix4x4t<TReal>& _this = *this;
   1.307 +
   1.308 +	// extract translation
   1.309 +	position.x = _this[0][3];
   1.310 +	position.y = _this[1][3];
   1.311 +	position.z = _this[2][3];
   1.312 +
   1.313 +	// extract rotation
   1.314 +	rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
   1.315 +}
   1.316 +
   1.317 +// ----------------------------------------------------------------------------------------
   1.318 +template <typename TReal>
   1.319 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
   1.320 +{
   1.321 +	return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
   1.322 +}
   1.323 +
   1.324 +// ----------------------------------------------------------------------------------------
   1.325 +template <typename TReal>
   1.326 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
   1.327 +{
   1.328 +	aiMatrix4x4t<TReal>& _this = *this;
   1.329 +
   1.330 +	TReal cr = cos( x );
   1.331 +	TReal sr = sin( x );
   1.332 +	TReal cp = cos( y );
   1.333 +	TReal sp = sin( y );
   1.334 +	TReal cy = cos( z );
   1.335 +	TReal sy = sin( z );
   1.336 +
   1.337 +	_this.a1 = cp*cy ;
   1.338 +	_this.a2 = cp*sy;
   1.339 +	_this.a3 = -sp ;
   1.340 +
   1.341 +	TReal srsp = sr*sp;
   1.342 +	TReal crsp = cr*sp;
   1.343 +
   1.344 +	_this.b1 = srsp*cy-cr*sy ;
   1.345 +	_this.b2 = srsp*sy+cr*cy ;
   1.346 +	_this.b3 = sr*cp ;
   1.347 +
   1.348 +	_this.c1 =  crsp*cy+sr*sy ;
   1.349 +	_this.c2 =  crsp*sy-sr*cy ;
   1.350 +	_this.c3 = cr*cp ;
   1.351 +
   1.352 +	return *this;
   1.353 +}
   1.354 +
   1.355 +// ----------------------------------------------------------------------------------------
   1.356 +template <typename TReal>
   1.357 +inline bool aiMatrix4x4t<TReal>::IsIdentity() const
   1.358 +{
   1.359 +	// Use a small epsilon to solve floating-point inaccuracies
   1.360 +	const static TReal epsilon = 10e-3f;
   1.361 +
   1.362 +	return (a2 <= epsilon && a2 >= -epsilon &&
   1.363 +			a3 <= epsilon && a3 >= -epsilon &&
   1.364 +			a4 <= epsilon && a4 >= -epsilon &&
   1.365 +			b1 <= epsilon && b1 >= -epsilon &&
   1.366 +			b3 <= epsilon && b3 >= -epsilon &&
   1.367 +			b4 <= epsilon && b4 >= -epsilon &&
   1.368 +			c1 <= epsilon && c1 >= -epsilon &&
   1.369 +			c2 <= epsilon && c2 >= -epsilon &&
   1.370 +			c4 <= epsilon && c4 >= -epsilon &&
   1.371 +			d1 <= epsilon && d1 >= -epsilon &&
   1.372 +			d2 <= epsilon && d2 >= -epsilon &&
   1.373 +			d3 <= epsilon && d3 >= -epsilon &&
   1.374 +			a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && 
   1.375 +			b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && 
   1.376 +			c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && 
   1.377 +			d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
   1.378 +}
   1.379 +
   1.380 +// ----------------------------------------------------------------------------------------
   1.381 +template <typename TReal>
   1.382 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
   1.383 +{
   1.384 +	/*
   1.385 +	     |  1  0       0       0 |
   1.386 +     M = |  0  cos(A) -sin(A)  0 |
   1.387 +         |  0  sin(A)  cos(A)  0 |
   1.388 +         |  0  0       0       1 |	*/
   1.389 +	out = aiMatrix4x4t<TReal>();
   1.390 +	out.b2 = out.c3 = cos(a);
   1.391 +	out.b3 = -(out.c2 = sin(a));
   1.392 +	return out;
   1.393 +}
   1.394 +
   1.395 +// ----------------------------------------------------------------------------------------
   1.396 +template <typename TReal>
   1.397 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
   1.398 +{
   1.399 +	/*
   1.400 +	     |  cos(A)  0   sin(A)  0 |
   1.401 +     M = |  0       1   0       0 |
   1.402 +         | -sin(A)  0   cos(A)  0 |
   1.403 +         |  0       0   0       1 |
   1.404 +		*/
   1.405 +	out = aiMatrix4x4t<TReal>();
   1.406 +	out.a1 = out.c3 = cos(a);
   1.407 +	out.c1 = -(out.a3 = sin(a));
   1.408 +	return out;
   1.409 +}
   1.410 +
   1.411 +// ----------------------------------------------------------------------------------------
   1.412 +template <typename TReal>
   1.413 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
   1.414 +{
   1.415 +	/*
   1.416 +	     |  cos(A)  -sin(A)   0   0 |
   1.417 +     M = |  sin(A)   cos(A)   0   0 |
   1.418 +         |  0        0        1   0 |
   1.419 +         |  0        0        0   1 |	*/
   1.420 +	out = aiMatrix4x4t<TReal>();
   1.421 +	out.a1 = out.b2 = cos(a);
   1.422 +	out.a2 = -(out.b1 = sin(a));
   1.423 +	return out;
   1.424 +}
   1.425 +
   1.426 +// ----------------------------------------------------------------------------------------
   1.427 +// Returns a rotation matrix for a rotation around an arbitrary axis.
   1.428 +template <typename TReal>
   1.429 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
   1.430 +{
   1.431 +  TReal c = cos( a), s = sin( a), t = 1 - c;
   1.432 +  TReal x = axis.x, y = axis.y, z = axis.z;
   1.433 +
   1.434 +  // Many thanks to MathWorld and Wikipedia
   1.435 +  out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
   1.436 +  out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
   1.437 +  out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
   1.438 +  out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
   1.439 +  out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
   1.440 +  out.d4 = static_cast<TReal>(1.0);
   1.441 +
   1.442 +  return out;
   1.443 +}
   1.444 +
   1.445 +// ----------------------------------------------------------------------------------------
   1.446 +template <typename TReal>
   1.447 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
   1.448 +{
   1.449 +	out = aiMatrix4x4t<TReal>();
   1.450 +	out.a4 = v.x;
   1.451 +	out.b4 = v.y;
   1.452 +	out.c4 = v.z;
   1.453 +	return out;
   1.454 +}
   1.455 +
   1.456 +// ----------------------------------------------------------------------------------------
   1.457 +template <typename TReal>
   1.458 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
   1.459 +{
   1.460 +	out = aiMatrix4x4t<TReal>();
   1.461 +	out.a1 = v.x;
   1.462 +	out.b2 = v.y;
   1.463 +	out.c3 = v.z;
   1.464 +	return out;
   1.465 +}
   1.466 +
   1.467 +// ----------------------------------------------------------------------------------------
   1.468 +/** A function for creating a rotation matrix that rotates a vector called
   1.469 + * "from" into another vector called "to".
   1.470 + * Input : from[3], to[3] which both must be *normalized* non-zero vectors
   1.471 + * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
   1.472 + * Authors: Tomas Möller, John Hughes
   1.473 + *          "Efficiently Building a Matrix to Rotate One Vector to Another"
   1.474 + *          Journal of Graphics Tools, 4(4):1-4, 1999
   1.475 + */
   1.476 +// ----------------------------------------------------------------------------------------
   1.477 +template <typename TReal>
   1.478 +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, 
   1.479 +	const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
   1.480 +{	
   1.481 +	aiMatrix3x3t<TReal> m3;
   1.482 +	aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
   1.483 +	mtx = aiMatrix4x4t<TReal>(m3);
   1.484 +	return mtx;
   1.485 +}
   1.486 +
   1.487 +#endif // __cplusplus
   1.488 +#endif // AI_MATRIX4x4_INL_INC