vrshoot

view libs/assimp/assimp/matrix3x3.inl @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
6 Copyright (c) 2006-2012, assimp team
8 All rights reserved.
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
42 /** @file aiMatrix3x3.inl
43 * @brief Inline implementation of the 3x3 matrix operators
44 */
45 #ifndef AI_MATRIX3x3_INL_INC
46 #define AI_MATRIX3x3_INL_INC
48 #ifdef __cplusplus
49 #include "matrix3x3.h"
51 #include "matrix4x4.h"
52 #include <algorithm>
53 #include <limits>
55 // ------------------------------------------------------------------------------------------------
56 // Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
57 template <typename TReal>
58 inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
59 {
60 a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
61 b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
62 c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
63 }
65 // ------------------------------------------------------------------------------------------------
66 template <typename TReal>
67 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
68 {
69 *this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
70 m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
71 m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
72 m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
73 m.a2 * b1 + m.b2 * b2 + m.c2 * b3,
74 m.a3 * b1 + m.b3 * b2 + m.c3 * b3,
75 m.a1 * c1 + m.b1 * c2 + m.c1 * c3,
76 m.a2 * c1 + m.b2 * c2 + m.c2 * c3,
77 m.a3 * c1 + m.b3 * c2 + m.c3 * c3);
78 return *this;
79 }
81 // ------------------------------------------------------------------------------------------------
82 template <typename TReal>
83 template <typename TOther>
84 aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
85 {
86 return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
87 static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
88 static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
89 }
91 // ------------------------------------------------------------------------------------------------
92 template <typename TReal>
93 inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
94 {
95 aiMatrix3x3t<TReal> temp( *this);
96 temp *= m;
97 return temp;
98 }
100 // ------------------------------------------------------------------------------------------------
101 template <typename TReal>
102 inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex)
103 {
104 return &this->a1 + p_iIndex * 3;
105 }
107 // ------------------------------------------------------------------------------------------------
108 template <typename TReal>
109 inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const
110 {
111 return &this->a1 + p_iIndex * 3;
112 }
114 // ------------------------------------------------------------------------------------------------
115 template <typename TReal>
116 inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
117 {
118 return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
119 b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
120 c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
121 }
123 // ------------------------------------------------------------------------------------------------
124 template <typename TReal>
125 inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
126 {
127 return !(*this == m);
128 }
130 // ------------------------------------------------------------------------------------------------
131 template <typename TReal>
132 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
133 {
134 // (TReal&) don't remove, GCC complains cause of packed fields
135 std::swap( (TReal&)a2, (TReal&)b1);
136 std::swap( (TReal&)a3, (TReal&)c1);
137 std::swap( (TReal&)b3, (TReal&)c2);
138 return *this;
139 }
141 // ----------------------------------------------------------------------------------------
142 template <typename TReal>
143 inline TReal aiMatrix3x3t<TReal>::Determinant() const
144 {
145 return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
146 }
148 // ----------------------------------------------------------------------------------------
149 template <typename TReal>
150 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
151 {
152 // Compute the reciprocal determinant
153 TReal det = Determinant();
154 if(det == static_cast<TReal>(0.0))
155 {
156 // Matrix not invertible. Setting all elements to nan is not really
157 // correct in a mathematical sense; but at least qnans are easy to
158 // spot. XXX we might throw an exception instead, which would
159 // be even much better to spot :/.
160 const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
161 *this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
163 return *this;
164 }
166 TReal invdet = static_cast<TReal>(1.0) / det;
168 aiMatrix3x3t<TReal> res;
169 res.a1 = invdet * (b2 * c3 - b3 * c2);
170 res.a2 = -invdet * (a2 * c3 - a3 * c2);
171 res.a3 = invdet * (a2 * b3 - a3 * b2);
172 res.b1 = -invdet * (b1 * c3 - b3 * c1);
173 res.b2 = invdet * (a1 * c3 - a3 * c1);
174 res.b3 = -invdet * (a1 * b3 - a3 * b1);
175 res.c1 = invdet * (b1 * c2 - b2 * c1);
176 res.c2 = -invdet * (a1 * c2 - a2 * c1);
177 res.c3 = invdet * (a1 * b2 - a2 * b1);
178 *this = res;
180 return *this;
181 }
183 // ------------------------------------------------------------------------------------------------
184 template <typename TReal>
185 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
186 {
187 out.a1 = out.b2 = ::cos(a);
188 out.b1 = ::sin(a);
189 out.a2 = - out.b1;
191 out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
192 out.c3 = 1.f;
194 return out;
195 }
197 // ------------------------------------------------------------------------------------------------
198 // Returns a rotation matrix for a rotation around an arbitrary axis.
199 template <typename TReal>
200 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
201 {
202 TReal c = cos( a), s = sin( a), t = 1 - c;
203 TReal x = axis.x, y = axis.y, z = axis.z;
205 // Many thanks to MathWorld and Wikipedia
206 out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
207 out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
208 out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
210 return out;
211 }
213 // ------------------------------------------------------------------------------------------------
214 template <typename TReal>
215 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
216 {
217 out = aiMatrix3x3t<TReal>();
218 out.a3 = v.x;
219 out.b3 = v.y;
220 return out;
221 }
223 // ----------------------------------------------------------------------------------------
224 /** A function for creating a rotation matrix that rotates a vector called
225 * "from" into another vector called "to".
226 * Input : from[3], to[3] which both must be *normalized* non-zero vectors
227 * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
228 * Authors: Tomas Möller, John Hughes
229 * "Efficiently Building a Matrix to Rotate One Vector to Another"
230 * Journal of Graphics Tools, 4(4):1-4, 1999
231 */
232 // ----------------------------------------------------------------------------------------
233 template <typename TReal>
234 inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
235 const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
236 {
237 const TReal e = from * to;
238 const TReal f = (e < 0)? -e:e;
240 if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001)) /* "from" and "to"-vector almost parallel */
241 {
242 aiVector3D u,v; /* temporary storage vectors */
243 aiVector3D x; /* vector most nearly orthogonal to "from" */
245 x.x = (from.x > 0.0)? from.x : -from.x;
246 x.y = (from.y > 0.0)? from.y : -from.y;
247 x.z = (from.z > 0.0)? from.z : -from.z;
249 if (x.x < x.y)
250 {
251 if (x.x < x.z)
252 {
253 x.x = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
254 }
255 else
256 {
257 x.z = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
258 }
259 }
260 else
261 {
262 if (x.y < x.z)
263 {
264 x.y = static_cast<TReal>(1.0); x.x = x.z = static_cast<TReal>(0.0);
265 }
266 else
267 {
268 x.z = static_cast<TReal>(1.0); x.x = x.y = static_cast<TReal>(0.0);
269 }
270 }
272 u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
273 v.x = x.x - to.x; v.y = x.y - to.y; v.z = x.z - to.z;
275 const TReal c1 = static_cast<TReal>(2.0) / (u * u);
276 const TReal c2 = static_cast<TReal>(2.0) / (v * v);
277 const TReal c3 = c1 * c2 * (u * v);
279 for (unsigned int i = 0; i < 3; i++)
280 {
281 for (unsigned int j = 0; j < 3; j++)
282 {
283 mtx[i][j] = - c1 * u[i] * u[j] - c2 * v[i] * v[j]
284 + c3 * v[i] * u[j];
285 }
286 mtx[i][i] += static_cast<TReal>(1.0);
287 }
288 }
289 else /* the most common case, unless "from"="to", or "from"=-"to" */
290 {
291 const aiVector3D v = from ^ to;
292 /* ... use this hand optimized version (9 mults less) */
293 const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e); /* optimization by Gottfried Chen */
294 const TReal hvx = h * v.x;
295 const TReal hvz = h * v.z;
296 const TReal hvxy = hvx * v.y;
297 const TReal hvxz = hvx * v.z;
298 const TReal hvyz = hvz * v.y;
299 mtx[0][0] = e + hvx * v.x;
300 mtx[0][1] = hvxy - v.z;
301 mtx[0][2] = hvxz + v.y;
303 mtx[1][0] = hvxy + v.z;
304 mtx[1][1] = e + h * v.y * v.y;
305 mtx[1][2] = hvyz - v.x;
307 mtx[2][0] = hvxz - v.y;
308 mtx[2][1] = hvyz + v.x;
309 mtx[2][2] = e + hvz * v.z;
310 }
311 return mtx;
312 }
315 #endif // __cplusplus
316 #endif // AI_MATRIX3x3_INL_INC