/src/ogre/OgreMain/src/OgreMatrix4.cpp
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | |
30 | | namespace Ogre |
31 | | { |
32 | | |
33 | | const Matrix4 Matrix4::ZERO( |
34 | | 0, 0, 0, 0, |
35 | | 0, 0, 0, 0, |
36 | | 0, 0, 0, 0, |
37 | | 0, 0, 0, 0 ); |
38 | | |
39 | | const Affine3 Affine3::ZERO( |
40 | | 0, 0, 0, 0, |
41 | | 0, 0, 0, 0, |
42 | | 0, 0, 0, 0); |
43 | | |
44 | | const Affine3 Affine3::IDENTITY( |
45 | | 1, 0, 0, 0, |
46 | | 0, 1, 0, 0, |
47 | | 0, 0, 1, 0); |
48 | | |
49 | | const Matrix4 Matrix4::IDENTITY( |
50 | | 1, 0, 0, 0, |
51 | | 0, 1, 0, 0, |
52 | | 0, 0, 1, 0, |
53 | | 0, 0, 0, 1 ); |
54 | | |
55 | | const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE( |
56 | | 0.5, 0, 0, 0.5, |
57 | | 0, -0.5, 0, 0.5, |
58 | | 0, 0, 1, 0, |
59 | | 0, 0, 0, 1); |
60 | | |
61 | | //----------------------------------------------------------------------- |
62 | | static Real |
63 | | MINOR(const TransformBaseReal& m, const size_t r0, const size_t r1, const size_t r2, |
64 | | const size_t c0, const size_t c1, const size_t c2) |
65 | 0 | { |
66 | 0 | return m[r0][c0] * (m[r1][c1] * m[r2][c2] - m[r2][c1] * m[r1][c2]) - |
67 | 0 | m[r0][c1] * (m[r1][c0] * m[r2][c2] - m[r2][c0] * m[r1][c2]) + |
68 | 0 | m[r0][c2] * (m[r1][c0] * m[r2][c1] - m[r2][c0] * m[r1][c1]); |
69 | 0 | } |
70 | | //----------------------------------------------------------------------- |
71 | | Matrix4 Matrix4::adjoint() const |
72 | 0 | { |
73 | 0 | return Matrix4( MINOR(*this, 1, 2, 3, 1, 2, 3), |
74 | 0 | -MINOR(*this, 0, 2, 3, 1, 2, 3), |
75 | 0 | MINOR(*this, 0, 1, 3, 1, 2, 3), |
76 | 0 | -MINOR(*this, 0, 1, 2, 1, 2, 3), |
77 | |
|
78 | 0 | -MINOR(*this, 1, 2, 3, 0, 2, 3), |
79 | 0 | MINOR(*this, 0, 2, 3, 0, 2, 3), |
80 | 0 | -MINOR(*this, 0, 1, 3, 0, 2, 3), |
81 | 0 | MINOR(*this, 0, 1, 2, 0, 2, 3), |
82 | |
|
83 | 0 | MINOR(*this, 1, 2, 3, 0, 1, 3), |
84 | 0 | -MINOR(*this, 0, 2, 3, 0, 1, 3), |
85 | 0 | MINOR(*this, 0, 1, 3, 0, 1, 3), |
86 | 0 | -MINOR(*this, 0, 1, 2, 0, 1, 3), |
87 | |
|
88 | 0 | -MINOR(*this, 1, 2, 3, 0, 1, 2), |
89 | 0 | MINOR(*this, 0, 2, 3, 0, 1, 2), |
90 | 0 | -MINOR(*this, 0, 1, 3, 0, 1, 2), |
91 | 0 | MINOR(*this, 0, 1, 2, 0, 1, 2)); |
92 | 0 | } |
93 | | //----------------------------------------------------------------------- |
94 | | Real TransformBaseReal::determinant() const |
95 | 0 | { |
96 | 0 | return m[0][0] * MINOR(*this, 1, 2, 3, 1, 2, 3) - |
97 | 0 | m[0][1] * MINOR(*this, 1, 2, 3, 0, 2, 3) + |
98 | 0 | m[0][2] * MINOR(*this, 1, 2, 3, 0, 1, 3) - |
99 | 0 | m[0][3] * MINOR(*this, 1, 2, 3, 0, 1, 2); |
100 | 0 | } |
101 | | //----------------------------------------------------------------------- |
102 | | Matrix4 Matrix4::inverse() const |
103 | 0 | { |
104 | 0 | Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3]; |
105 | 0 | Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3]; |
106 | 0 | Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3]; |
107 | 0 | Real m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3]; |
108 | |
|
109 | 0 | Real v0 = m20 * m31 - m21 * m30; |
110 | 0 | Real v1 = m20 * m32 - m22 * m30; |
111 | 0 | Real v2 = m20 * m33 - m23 * m30; |
112 | 0 | Real v3 = m21 * m32 - m22 * m31; |
113 | 0 | Real v4 = m21 * m33 - m23 * m31; |
114 | 0 | Real v5 = m22 * m33 - m23 * m32; |
115 | |
|
116 | 0 | Real t00 = + (v5 * m11 - v4 * m12 + v3 * m13); |
117 | 0 | Real t10 = - (v5 * m10 - v2 * m12 + v1 * m13); |
118 | 0 | Real t20 = + (v4 * m10 - v2 * m11 + v0 * m13); |
119 | 0 | Real t30 = - (v3 * m10 - v1 * m11 + v0 * m12); |
120 | |
|
121 | 0 | Real invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03); |
122 | |
|
123 | 0 | Real d00 = t00 * invDet; |
124 | 0 | Real d10 = t10 * invDet; |
125 | 0 | Real d20 = t20 * invDet; |
126 | 0 | Real d30 = t30 * invDet; |
127 | |
|
128 | 0 | Real d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet; |
129 | 0 | Real d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet; |
130 | 0 | Real d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet; |
131 | 0 | Real d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet; |
132 | |
|
133 | 0 | v0 = m10 * m31 - m11 * m30; |
134 | 0 | v1 = m10 * m32 - m12 * m30; |
135 | 0 | v2 = m10 * m33 - m13 * m30; |
136 | 0 | v3 = m11 * m32 - m12 * m31; |
137 | 0 | v4 = m11 * m33 - m13 * m31; |
138 | 0 | v5 = m12 * m33 - m13 * m32; |
139 | |
|
140 | 0 | Real d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet; |
141 | 0 | Real d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet; |
142 | 0 | Real d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet; |
143 | 0 | Real d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet; |
144 | |
|
145 | 0 | v0 = m21 * m10 - m20 * m11; |
146 | 0 | v1 = m22 * m10 - m20 * m12; |
147 | 0 | v2 = m23 * m10 - m20 * m13; |
148 | 0 | v3 = m22 * m11 - m21 * m12; |
149 | 0 | v4 = m23 * m11 - m21 * m13; |
150 | 0 | v5 = m23 * m12 - m22 * m13; |
151 | |
|
152 | 0 | Real d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet; |
153 | 0 | Real d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet; |
154 | 0 | Real d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet; |
155 | 0 | Real d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet; |
156 | |
|
157 | 0 | return Matrix4( |
158 | 0 | d00, d01, d02, d03, |
159 | 0 | d10, d11, d12, d13, |
160 | 0 | d20, d21, d22, d23, |
161 | 0 | d30, d31, d32, d33); |
162 | 0 | } |
163 | | //----------------------------------------------------------------------- |
164 | | Affine3 Affine3::inverse() const |
165 | 0 | { |
166 | 0 | Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2]; |
167 | 0 | Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2]; |
168 | |
|
169 | 0 | Real t00 = m22 * m11 - m21 * m12; |
170 | 0 | Real t10 = m20 * m12 - m22 * m10; |
171 | 0 | Real t20 = m21 * m10 - m20 * m11; |
172 | |
|
173 | 0 | Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2]; |
174 | |
|
175 | 0 | Real invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20); |
176 | |
|
177 | 0 | t00 *= invDet; t10 *= invDet; t20 *= invDet; |
178 | |
|
179 | 0 | m00 *= invDet; m01 *= invDet; m02 *= invDet; |
180 | |
|
181 | 0 | Real r00 = t00; |
182 | 0 | Real r01 = m02 * m21 - m01 * m22; |
183 | 0 | Real r02 = m01 * m12 - m02 * m11; |
184 | |
|
185 | 0 | Real r10 = t10; |
186 | 0 | Real r11 = m00 * m22 - m02 * m20; |
187 | 0 | Real r12 = m02 * m10 - m00 * m12; |
188 | |
|
189 | 0 | Real r20 = t20; |
190 | 0 | Real r21 = m01 * m20 - m00 * m21; |
191 | 0 | Real r22 = m00 * m11 - m01 * m10; |
192 | |
|
193 | 0 | Real m03 = m[0][3], m13 = m[1][3], m23 = m[2][3]; |
194 | |
|
195 | 0 | Real r03 = - (r00 * m03 + r01 * m13 + r02 * m23); |
196 | 0 | Real r13 = - (r10 * m03 + r11 * m13 + r12 * m23); |
197 | 0 | Real r23 = - (r20 * m03 + r21 * m13 + r22 * m23); |
198 | |
|
199 | 0 | return Affine3( |
200 | 0 | r00, r01, r02, r03, |
201 | 0 | r10, r11, r12, r13, |
202 | 0 | r20, r21, r22, r23); |
203 | 0 | } |
204 | | //----------------------------------------------------------------------- |
205 | | void TransformBaseReal::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) |
206 | 0 | { |
207 | | // Ordering: |
208 | | // 1. Scale |
209 | | // 2. Rotate |
210 | | // 3. Translate |
211 | |
|
212 | 0 | Matrix3 rot3x3; |
213 | 0 | orientation.ToRotationMatrix(rot3x3); |
214 | | |
215 | | // Set up final matrix with scale, rotation and translation |
216 | 0 | m[0][0] = scale.x * rot3x3[0][0]; m[0][1] = scale.y * rot3x3[0][1]; m[0][2] = scale.z * rot3x3[0][2]; m[0][3] = position.x; |
217 | 0 | m[1][0] = scale.x * rot3x3[1][0]; m[1][1] = scale.y * rot3x3[1][1]; m[1][2] = scale.z * rot3x3[1][2]; m[1][3] = position.y; |
218 | 0 | m[2][0] = scale.x * rot3x3[2][0]; m[2][1] = scale.y * rot3x3[2][1]; m[2][2] = scale.z * rot3x3[2][2]; m[2][3] = position.z; |
219 | | |
220 | | // No projection term |
221 | 0 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; |
222 | 0 | } |
223 | | //----------------------------------------------------------------------- |
224 | | void TransformBaseReal::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation) |
225 | 0 | { |
226 | | // Invert the parameters |
227 | 0 | Vector3 invTranslate = -position; |
228 | 0 | Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z); |
229 | 0 | Quaternion invRot = orientation.Inverse(); |
230 | | |
231 | | // Because we're inverting, order is translation, rotation, scale |
232 | | // So make translation relative to scale & rotation |
233 | 0 | invTranslate = invRot * invTranslate; // rotate |
234 | 0 | invTranslate *= invScale; // scale |
235 | | |
236 | | // Next, make a 3x3 rotation matrix |
237 | 0 | Matrix3 rot3x3; |
238 | 0 | invRot.ToRotationMatrix(rot3x3); |
239 | | |
240 | | // Set up final matrix with scale, rotation and translation |
241 | 0 | m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x; |
242 | 0 | m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y; |
243 | 0 | m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z; |
244 | | |
245 | | // No projection term |
246 | 0 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; |
247 | 0 | } |
248 | | //----------------------------------------------------------------------- |
249 | | void Affine3::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const |
250 | 0 | { |
251 | 0 | Matrix3 matQ; |
252 | 0 | Vector3 vecU; |
253 | 0 | linear().QDUDecomposition( matQ, scale, vecU ); |
254 | |
|
255 | 0 | orientation = Quaternion( matQ ); |
256 | 0 | position = Vector3( m[0][3], m[1][3], m[2][3] ); |
257 | 0 | } |
258 | | |
259 | | } |