source: nanovis/trunk/vrmath/Matrix4x4f.cpp @ 4905

Last change on this file since 4905 was 4905, checked in by ldelgass, 10 years ago

Apply matrix changes from double to float version

File size: 27.8 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 *
5 * Author: Insoo Woo <iwoo@purdue.edu>
6 * Author: Leif Delgass <ldelgass@purdue.edu>
7 */
8
9#include <vrmath/Vector3f.h>
10#include <vrmath/Rotation.h>
11#include <vrmath/Matrix4x4f.h>
12
13using namespace vrmath;
14
15void Matrix4x4f::makeIdentity()
16{
17    _data[1] = _data[2] = _data[3] = _data[4] =
18        _data[6] = _data[7] = _data[8] = _data[9] =
19        _data[11] = _data[12] = _data[13] = _data[14] = 0.0f;
20    _data[0] = _data[5] = _data[10] = _data[15] = 1.0f;
21}
22
23void Matrix4x4f::makeTranslation(const Vector3f& translation)
24{
25    _data[1] = _data[2] = _data[3] = _data[4] =
26        _data[6] = _data[7] = _data[8] = _data[9] =
27        _data[11] = 0.0f;
28    _data[0] = _data[5] = _data[10] = _data[15] = 1.0f;
29    _data[12] = translation.x;
30    _data[13] = translation.y;
31    _data[14] = translation.z;
32}
33
34void Matrix4x4f::makeTranslation(float x, float y, float z)
35{
36    _data[1] = _data[2] = _data[3] = _data[4] =
37        _data[6] = _data[7] = _data[8] = _data[9] =
38        _data[11] = 0.0f;
39    _data[0] = _data[5] = _data[10] = _data[15] = 1.0f;
40    _data[12] = x;
41    _data[13] = y;
42    _data[14] = z;
43}
44
45void Matrix4x4f::makeRotation(const Rotation& rotation)
46{
47    if (rotation.getAngle() == 0.0 ||
48        (rotation.getX() == 0.0 &&
49         rotation.getY() == 0.0 &&
50         rotation.getZ() == 0.0)) {
51        makeIdentity();
52        return;
53    }
54
55    double xAxis = rotation.getX();
56    double yAxis = rotation.getY();
57    double zAxis = rotation.getZ();
58    double invLen = 1.0 / sqrt(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis);
59    double cosine = cos(rotation.getAngle());
60    double sine = sin(rotation.getAngle());
61
62    xAxis *= invLen;
63    yAxis *= invLen;
64    zAxis *= invLen;
65
66    double oneMinusCosine = 1.0 - cosine;
67
68    _data[3] = _data[7] = _data[11] = _data[12] = _data[13] = _data[14] = 0.0f;
69    _data[15] = 1.0f;
70
71    _data[0] = float(xAxis * xAxis * oneMinusCosine + cosine);
72    _data[1] = float(yAxis * xAxis * oneMinusCosine + zAxis * sine);
73    _data[2] = float(xAxis * zAxis * oneMinusCosine - yAxis * sine);
74
75    _data[4] = float(xAxis * yAxis * oneMinusCosine - zAxis * sine);
76    _data[5] = float(yAxis * yAxis * oneMinusCosine + cosine);
77    _data[6] = float(yAxis * zAxis * oneMinusCosine + xAxis * sine);
78
79    _data[8] = float(xAxis * zAxis * oneMinusCosine + yAxis * sine);
80    _data[9] = float(yAxis * zAxis * oneMinusCosine - xAxis * sine);
81    _data[10] = float(zAxis * zAxis * oneMinusCosine + cosine);
82}
83
84void Matrix4x4f::makeRotation(double xAxis, double yAxis, double zAxis, double angle)
85{
86    if (angle == 0.0 ||
87        (xAxis == 0.0 &&
88         yAxis == 0.0 &&
89         zAxis == 0.0)) {
90        makeIdentity();
91        return;
92    }
93
94    double invLen = 1.0 / sqrt((double)xAxis * xAxis + (double)yAxis * yAxis + (double)zAxis * zAxis);
95    double cosine = cos(angle);
96    double sine = sin(angle);
97
98    xAxis *= invLen;
99    yAxis *= invLen;
100    zAxis *= invLen;
101
102    double oneMinusCosine = 1.0 - cosine;
103
104    _data[3] = _data[7] = _data[11] = _data[12] = _data[13] = _data[14] = 0.0f;
105    _data[15] = 1.0f;
106
107    _data[0] = float(xAxis * xAxis * oneMinusCosine + cosine);
108    _data[1] = float(yAxis * xAxis * oneMinusCosine + zAxis * sine);
109    _data[2] = float(xAxis * zAxis * oneMinusCosine - yAxis * sine);
110
111    _data[4] = float(xAxis * yAxis * oneMinusCosine - zAxis * sine);
112    _data[5] = float(yAxis * yAxis * oneMinusCosine + cosine);
113    _data[6] = float(yAxis * zAxis * oneMinusCosine + xAxis * sine);
114
115    _data[8] = float(xAxis * zAxis * oneMinusCosine + yAxis * sine);
116    _data[9] = float(yAxis * zAxis * oneMinusCosine - xAxis * sine);
117    _data[10] = float(zAxis * zAxis * oneMinusCosine + cosine);
118}
119
120void Matrix4x4f::makeScale(const Vector3f& scale)
121{
122    _data[1] = _data[2] = _data[3] = _data[4] =
123        _data[6] = _data[7] = _data[8] = _data[9] =
124        _data[11] = 0.0f;
125
126    _data[0] = scale.x;
127    _data[5] = scale.y;
128    _data[10] = scale.z;
129
130    _data[15] = 1.0f;
131    _data[12] = _data[13] = _data[14] = 0.0f;
132}
133
134void Matrix4x4f::makeScale(float x, float y, float z)
135{
136    _data[1] = _data[2] = _data[3] = _data[4] =
137        _data[6] = _data[7] = _data[8] = _data[9] =
138        _data[11] = 0.0f;
139
140    _data[0] = x;
141    _data[5] = y;
142    _data[10] = z;
143
144    _data[15] = 1.0f;
145    _data[12] = _data[13] = _data[14] = 0.0f;
146}
147
148Vector4f
149Matrix4x4f::transform(const Vector4f& v) const
150{
151    Vector4f ret;
152    ret.x = _data[0] * v.x + _data[4] * v.y + _data[8] * v.z  + _data[12] * v.w;
153    ret.y = _data[1] * v.x + _data[5] * v.y + _data[9] * v.z  + _data[13] * v.w;
154    ret.z = _data[2] * v.x + _data[6] * v.y + _data[10] * v.z + _data[14] * v.w;
155    ret.w = _data[3] * v.x + _data[7] * v.y + _data[11] * v.z + _data[15] * v.w;
156    return ret;
157}
158
159Vector3f
160Matrix4x4f::transformVec(const Vector3f& v) const
161{
162    Vector3f ret;
163    ret.x = _data[0] * v.x + _data[4] * v.y + _data[8] * v.z;
164    ret.y = _data[1] * v.x + _data[5] * v.y + _data[9] * v.z;
165    ret.z = _data[2] * v.x + _data[6] * v.y + _data[10] * v.z;
166    return ret;
167}
168
169Vector4f
170Matrix4x4f::preMultiplyRowVector(const Vector4f& v) const
171{
172    Vector4f ret;
173    ret.x = (_data[0]  * v.x) + (_data[1]  * v.y) + (_data[2]  * v.z) + (_data[3]  * v.w);
174    ret.y = (_data[4]  * v.x) + (_data[5]  * v.y) + (_data[6]  * v.z) + (_data[7]  * v.w);
175    ret.z = (_data[8]  * v.x) + (_data[9]  * v.y) + (_data[10] * v.z) + (_data[11] * v.w);
176    ret.w = (_data[12] * v.x) + (_data[13] * v.y) + (_data[14] * v.z) + (_data[15] * v.w);
177    return ret;
178}
179
180void Matrix4x4f::multiply(const Matrix4x4f& m1)
181{
182    float mat[16];
183    const float *mat1 = m1._data;
184
185    // 1 row
186    mat[0] = float(_data[0] * mat1[0] + _data[4] * mat1[1] +
187                   _data[8] * mat1[2] + _data[12] * mat1[3]);
188    mat[4] = float(_data[0] * mat1[4] + _data[4] * mat1[5] +
189                   _data[8] * mat1[6] + _data[12] * mat1[7]);
190    mat[8] = float(_data[0] * mat1[8] + _data[4] * mat1[9] +
191                   _data[8] * mat1[10] + _data[12] * mat1[11]);
192    mat[12] = float(_data[0] * mat1[12] + _data[4] * mat1[13] +
193                    _data[8] * mat1[14] + _data[12] * mat1[15]);
194
195    // 2 row
196    mat[1] = float(_data[1] * mat1[0] + _data[5] * mat1[1] +
197                   _data[9] * mat1[2] + _data[13] * mat1[3]);
198    mat[5] = float(_data[1] * mat1[4] + _data[5] * mat1[5] +
199                   _data[9] * mat1[6] + _data[13] * mat1[7]);
200    mat[9] = float(_data[1] * mat1[8] + _data[5] * mat1[9] +
201                   _data[9] * mat1[10] + _data[13] * mat1[11]);
202    mat[13] = float(_data[1] * mat1[12] + _data[5] * mat1[13] +
203                    _data[9] * mat1[14] + _data[13] * mat1[15]);
204
205    // 3 row
206    mat[2] = float(_data[2] * mat1[0] + _data[6] * mat1[1] +
207                   _data[10] * mat1[2] + _data[14] * mat1[3]);
208
209    mat[6] = float(_data[2] * mat1[4] + _data[6] * mat1[5] +
210                   _data[10] * mat1[6] + _data[14] * mat1[7]);
211    mat[10] = float(_data[2] * mat1[8] + _data[6] * mat1[9] +
212                    _data[10] * mat1[10] + _data[14] * mat1[11]);
213    mat[14] = float(_data[2] * mat1[12] + _data[6] * mat1[13] +
214                    _data[10] * mat1[14] + _data[14] * mat1[15]);
215
216    // 4 row
217    mat[3] = float(_data[3] * mat1[0] + _data[7] * mat1[1] +
218                   _data[11] * mat1[2] + _data[15] * mat1[3]);
219    mat[7] = float(_data[3] * mat1[4] + _data[7] * mat1[5] +
220                   _data[11] * mat1[6] + _data[15] * mat1[7]);
221    mat[11] = float(_data[3] * mat1[8] + _data[7] * mat1[9] +
222                    _data[11] * mat1[10] + _data[15] * mat1[11]);
223    mat[15] = float(_data[3] * mat1[12] + _data[7] * mat1[13] +
224                    _data[11] * mat1[14] + _data[15] * mat1[15]);
225
226    // set matrix
227    set(mat);
228}
229
230void Matrix4x4f::multiply(const Matrix4x4f& m1, const Matrix4x4f& m2)
231{
232    if (&m1 == this && &m2 != this) {
233        multiply(m2);
234    } else if (&m1 != this && &m2 != this) {
235        multiplyFast(m1, m2);
236    } else {
237        float mat[16];
238        const float *mat1 = m1._data;
239        const float *mat2 = m2._data;
240
241        // 1 row
242        mat[0] = float(mat1[0] * mat2[0] + mat1[4] * mat2[1] +
243                       mat1[8] * mat2[2] + mat1[12] * mat2[3]);
244        mat[4] = float(mat1[0] * mat2[4] + mat1[4] * mat2[5] +
245                       mat1[8] * mat2[6] + mat1[12] * mat2[7]);
246        mat[8] = float(mat1[0] * mat2[8] + mat1[4] * mat2[9] +
247                       mat1[8] * mat2[10] + mat1[12] * mat2[11]);
248        mat[12] = float(mat1[0] * mat2[12] + mat1[4] * mat2[13] +
249                        mat1[8] * mat2[14] + mat1[12] * mat2[15]);
250
251        // 2 row
252        mat[1] = float(mat1[1] * mat2[0] + mat1[5] * mat2[1] +
253                       mat1[9] * mat2[2] + mat1[13] * mat2[3]);
254        mat[5] = float(mat1[1] * mat2[4] + mat1[5] * mat2[5] +
255                       mat1[9] * mat2[6] + mat1[13] * mat2[7]);
256        mat[9] = float(mat1[1] * mat2[8] + mat1[5] * mat2[9] +
257                       mat1[9] * mat2[10] + mat1[13] * mat2[11]);
258        mat[13] = float(mat1[1] * mat2[12] + mat1[5] * mat2[13] +
259                        mat1[9] * mat2[14] + mat1[13] * mat2[15]);
260
261        // 3 row
262        mat[2] = float(mat1[2] * mat2[0] + mat1[6] * mat2[1] +
263                       mat1[10] * mat2[2] + mat1[14] * mat2[3]);
264        mat[6] = float(mat1[2] * mat2[4] + mat1[6] * mat2[5] +
265                       mat1[10] * mat2[6] + mat1[14] * mat2[7]);
266        mat[10] = float(mat1[2] * mat2[8] + mat1[6] * mat2[9] +
267                        mat1[10] * mat2[10] + mat1[14] * mat2[11]);
268        mat[14] = float(mat1[2] * mat2[12] + mat1[6] * mat2[13] +
269                        mat1[10] * mat2[14] + mat1[14] * mat2[15]);
270
271        // 4 row
272        mat[3] = float(mat1[3] * mat2[0] + mat1[7] * mat2[1] +
273                       mat1[11] * mat2[2] + mat1[15] * mat2[3]);
274        mat[7] = float(mat1[3] * mat2[4] + mat1[7] * mat2[5] +
275                       mat1[11] * mat2[6] + mat1[15] * mat2[7]);
276        mat[11] = float(mat1[3] * mat2[8] + mat1[7] * mat2[9] +
277                        mat1[11] * mat2[10] + mat1[15] * mat2[11]);
278        mat[15] = float(mat1[3] * mat2[12] + mat1[7] * mat2[13] +
279                        mat1[11] * mat2[14] + mat1[15] * mat2[15]);
280
281        // set matrix
282        set(mat);
283    }
284}
285
286void Matrix4x4f::multiplyFast(const Matrix4x4f& m1, const Matrix4x4f& m2)
287{
288    const float *mat1 = m1._data;
289    const float *mat2 = m2._data;
290
291    // 1 row
292    _data[0] = float(mat1[0] * mat2[0] + mat1[4] * mat2[1] +
293                     mat1[8] * mat2[2] + mat1[12] * mat2[3]);
294    _data[4] = float(mat1[0] * mat2[4] + mat1[4] * mat2[5] +
295                     mat1[8] * mat2[6] + mat1[12] * mat2[7]);
296    _data[8] = float(mat1[0] * mat2[8] + mat1[4] * mat2[9] +
297                     mat1[8] * mat2[10] + mat1[12] * mat2[11]);
298    _data[12] = float(mat1[0] * mat2[12] + mat1[4] * mat2[13] +
299                      mat1[8] * mat2[14] + mat1[12] * mat2[15]);
300
301    // 2 row
302    _data[1] = float(mat1[1] * mat2[0] + mat1[5] * mat2[1] +
303                     mat1[9] * mat2[2] + mat1[13] * mat2[3]);
304    _data[5] = float(mat1[1] * mat2[4] + mat1[5] * mat2[5] +
305                     mat1[9] * mat2[6] + mat1[13] * mat2[7]);
306    _data[9] = float(mat1[1] * mat2[8] + mat1[5] * mat2[9] +
307                     mat1[9] * mat2[10] + mat1[13] * mat2[11]);
308    _data[13] = float(mat1[1] * mat2[12] + mat1[5] * mat2[13] +
309                      mat1[9] * mat2[14] + mat1[13] * mat2[15]);
310
311    // 3 row
312    _data[2] = float(mat1[2] * mat2[0] + mat1[6] * mat2[1] +
313                     mat1[10] * mat2[2] + mat1[14] * mat2[3]);
314    _data[6] = float(mat1[2] * mat2[4] + mat1[6] * mat2[5] +
315                     mat1[10] * mat2[6] + mat1[14] * mat2[7]);
316    _data[10] = float(mat1[2] * mat2[8] + mat1[6] * mat2[9] +
317                      mat1[10] * mat2[10] + mat1[14] * mat2[11]);
318    _data[14] = float(mat1[2] * mat2[12] + mat1[6] * mat2[13] +
319                      mat1[10] * mat2[14] + mat1[14] * mat2[15]);
320
321    // 4 row
322    _data[3] = float(mat1[3] * mat2[0] + mat1[7] * mat2[1] +
323                     mat1[11] * mat2[2] + mat1[15] * mat2[3]);
324    _data[7] = float(mat1[3] * mat2[4] + mat1[7] * mat2[5] +
325                     mat1[11] * mat2[6] + mat1[15] * mat2[7]);
326    _data[11] = float(mat1[3] * mat2[8] + mat1[7] * mat2[9] +
327                      mat1[11] * mat2[10] + mat1[15] * mat2[11]);
328    _data[15] = float(mat1[3] * mat2[12] + mat1[7] * mat2[13] +
329                      mat1[11] * mat2[14] + mat1[15] * mat2[15]);
330}
331
332void Matrix4x4f::getRotation(Rotation& rotation)
333{
334    double c = (_data[0] + _data[5] + _data[10] - 1.0) * 0.5;
335
336    rotation.setAxis(_data[6] - _data[9], _data[8] - _data[2], _data[1] - _data[4]);
337
338    double len = sqrt(rotation.getX() * rotation.getX() +
339                      rotation.getY() * rotation.getY() +
340                      rotation.getZ() * rotation.getZ());
341
342    double s = 0.5 * len;
343
344    rotation.setAngle(atan2(s, c));
345
346    if (rotation.getX() == 0.0 &&
347        rotation.getY() == 0.0 &&
348        rotation.getZ() == 0.0) {
349        rotation.set(0, 1, 0, 0);
350    } else {
351        len = 1.0 / len;
352        rotation.setAxis(rotation.getX() * len,
353                         rotation.getY() * len,
354                         rotation.getZ() * len);
355    }
356}
357
358void Matrix4x4f::invert()
359{
360    float det =
361        _data[12] * _data[9] * _data[6] * _data[3]-
362        _data[8] * _data[13] * _data[6] * _data[3]-
363        _data[12] * _data[5] * _data[10] * _data[3]+
364        _data[4] * _data[13] * _data[10] * _data[3]+
365        _data[8] * _data[5] * _data[14] * _data[3]-
366        _data[4] * _data[9] * _data[14] * _data[3]-
367        _data[12] * _data[9] * _data[2] * _data[7]+
368        _data[8] * _data[13] * _data[2] * _data[7]+
369        _data[12] * _data[1] * _data[10] * _data[7]-
370        _data[0] * _data[13] * _data[10] * _data[7]-
371        _data[8] * _data[1] * _data[14] * _data[7]+
372        _data[0] * _data[9] * _data[14] * _data[7]+
373        _data[12] * _data[5] * _data[2] * _data[11]-
374        _data[4] * _data[13] * _data[2] * _data[11]-
375        _data[12] * _data[1] * _data[6] * _data[11]+
376        _data[0] * _data[13] * _data[6] * _data[11]+
377        _data[4] * _data[1] * _data[14] * _data[11]-
378        _data[0] * _data[5] * _data[14] * _data[11]-
379        _data[8] * _data[5] * _data[2] * _data[15]+
380        _data[4] * _data[9] * _data[2] * _data[15]+
381        _data[8] * _data[1] * _data[6] * _data[15]-
382        _data[0] * _data[9] * _data[6] * _data[15]-
383        _data[4] * _data[1] * _data[10] * _data[15]+
384        _data[0] * _data[5] * _data[10] * _data[15];
385
386    if ( det == 0.0f ) return;
387    det = 1 / det;
388
389    float mat[16];
390
391    mat[0] = (_data[9]*_data[14]*_data[7] -
392              _data[13]*_data[10]*_data[7] +
393              _data[13]*_data[6]*_data[11] -
394              _data[5]*_data[14]*_data[11] -
395              _data[9]*_data[6]*_data[15] +
396              _data[5]*_data[10]*_data[15]) * det;
397
398    mat[4] = (_data[12]*_data[10]*_data[7] -
399              _data[8]*_data[14]*_data[7] -
400              _data[12]*_data[6]*_data[11] +
401              _data[4]*_data[14]*_data[11] +
402              _data[8]*_data[6]*_data[15] -
403              _data[4]*_data[10]*_data[15]) * det;
404
405    mat[8] = (_data[8]*_data[13]*_data[7] -
406              _data[12]*_data[9]*_data[7] +
407              _data[12]*_data[5]*_data[11] -
408              _data[4]*_data[13]*_data[11] -
409              _data[8]*_data[5]*_data[15] +
410              _data[4]*_data[9]*_data[15]) * det;
411
412    mat[12] = (_data[12]*_data[9]*_data[6] -
413               _data[8]*_data[13]*_data[6] -
414               _data[12]*_data[5]*_data[10] +
415               _data[4]*_data[13]*_data[10] +
416               _data[8]*_data[5]*_data[14] -
417               _data[4]*_data[9]*_data[14]) * det;
418
419    mat[1] = (_data[13]*_data[10]*_data[3] -
420              _data[9]*_data[14]*_data[3] -
421              _data[13]*_data[2]*_data[11] +
422              _data[1]*_data[14]*_data[11] +
423              _data[9]*_data[2]*_data[15] -
424              _data[1]*_data[10]*_data[15]) * det;
425
426    mat[5] = (_data[8]*_data[14]*_data[3] -
427              _data[12]*_data[10]*_data[3] +
428              _data[12]*_data[2]*_data[11] -
429              _data[0]*_data[14]*_data[11] -
430              _data[8]*_data[2]*_data[15] +
431              _data[0]*_data[10]*_data[15]) * det;
432
433    mat[9] = (_data[12]*_data[9]*_data[3] -
434              _data[8]*_data[13]*_data[3] -
435              _data[12]*_data[1]*_data[11] +
436              _data[0]*_data[13]*_data[11] +
437              _data[8]*_data[1]*_data[15] -
438              _data[0]*_data[9]*_data[15]) * det;
439
440    mat[13] = (_data[8]*_data[13]*_data[2] -
441               _data[12]*_data[9]*_data[2] +
442               _data[12]*_data[1]*_data[10] -
443               _data[0]*_data[13]*_data[10] -
444               _data[8]*_data[1]*_data[14] +
445               _data[0]*_data[9]*_data[14]) * det;
446
447    mat[2] = (_data[5]*_data[14]*_data[3] -
448              _data[13]*_data[6]*_data[3] +
449              _data[13]*_data[2]*_data[7] -
450              _data[1]*_data[14]*_data[7] -
451              _data[5]*_data[2]*_data[15] +
452              _data[1]*_data[6]*_data[15]) * det;
453
454    mat[6] = (_data[12]*_data[6]*_data[3] -
455              _data[4]*_data[14]*_data[3] -
456              _data[12]*_data[2]*_data[7] +
457              _data[0]*_data[14]*_data[7] +
458              _data[4]*_data[2]*_data[15] -
459              _data[0]*_data[6]*_data[15]) * det;
460
461    mat[10] = (_data[4]*_data[13]*_data[3] -
462               _data[12]*_data[5]*_data[3] +
463               _data[12]*_data[1]*_data[7] -
464               _data[0]*_data[13]*_data[7] -
465               _data[4]*_data[1]*_data[15] +
466               _data[0]*_data[5]*_data[15]) * det;
467
468    mat[14] = (_data[12]*_data[5]*_data[2] -
469               _data[4]*_data[13]*_data[2] -
470               _data[12]*_data[1]*_data[6] +
471               _data[0]*_data[13]*_data[6] +
472               _data[4]*_data[1]*_data[14] -
473               _data[0]*_data[5]*_data[14]) * det;
474
475    mat[3] = (_data[9]*_data[6]*_data[3] -
476              _data[5]*_data[10]*_data[3] -
477              _data[9]*_data[2]*_data[7] +
478              _data[1]*_data[10]*_data[7] +
479              _data[5]*_data[2]*_data[11] -
480              _data[1]*_data[6]*_data[11]) * det;
481
482    mat[7] = (_data[4]*_data[10]*_data[3] -
483              _data[8]*_data[6]*_data[3] +
484              _data[8]*_data[2]*_data[7] -
485              _data[0]*_data[10]*_data[7] -
486              _data[4]*_data[2]*_data[11] +
487              _data[0]*_data[6]*_data[11]) * det;
488
489    mat[11] = (_data[8]*_data[5]*_data[3] -
490               _data[4]*_data[9]*_data[3] -
491               _data[8]*_data[1]*_data[7] +
492               _data[0]*_data[9]*_data[7] +
493               _data[4]*_data[1]*_data[11] -
494               _data[0]*_data[5]*_data[11]) * det;
495
496    mat[15] = (_data[4]*_data[9]*_data[2] -
497               _data[8]*_data[5]*_data[2] +
498               _data[8]*_data[1]*_data[6] -
499               _data[0]*_data[9]*_data[6] -
500               _data[4]*_data[1]*_data[10] +
501               _data[0]*_data[5]*_data[10]) * det;
502
503    set(mat);
504}
505
506void Matrix4x4f::invert(const Matrix4x4f& mat)
507{
508    if (&mat == this) {
509        invert();
510    } else {
511        invertFast(mat);
512    }
513}
514
515void Matrix4x4f::invertFast(const Matrix4x4f& mat)
516{
517    float *srcData = (float *)mat._data;
518
519    float det =
520        srcData[12] * srcData[9] * srcData[6] * srcData[3]-
521        srcData[8] * srcData[13] * srcData[6] * srcData[3]-
522        srcData[12] * srcData[5] * srcData[10] * srcData[3]+
523        srcData[4] * srcData[13] * srcData[10] * srcData[3]+
524        srcData[8] * srcData[5] * srcData[14] * srcData[3]-
525        srcData[4] * srcData[9] * srcData[14] * srcData[3]-
526        srcData[12] * srcData[9] * srcData[2] * srcData[7]+
527        srcData[8] * srcData[13] * srcData[2] * srcData[7]+
528        srcData[12] * srcData[1] * srcData[10] * srcData[7]-
529        srcData[0] * srcData[13] * srcData[10] * srcData[7]-
530        srcData[8] * srcData[1] * srcData[14] * srcData[7]+
531        srcData[0] * srcData[9] * srcData[14] * srcData[7]+
532        srcData[12] * srcData[5] * srcData[2] * srcData[11]-
533        srcData[4] * srcData[13] * srcData[2] * srcData[11]-
534        srcData[12] * srcData[1] * srcData[6] * srcData[11]+
535        srcData[0] * srcData[13] * srcData[6] * srcData[11]+
536        srcData[4] * srcData[1] * srcData[14] * srcData[11]-
537        srcData[0] * srcData[5] * srcData[14] * srcData[11]-
538        srcData[8] * srcData[5] * srcData[2] * srcData[15]+
539        srcData[4] * srcData[9] * srcData[2] * srcData[15]+
540        srcData[8] * srcData[1] * srcData[6] * srcData[15]-
541        srcData[0] * srcData[9] * srcData[6] * srcData[15]-
542        srcData[4] * srcData[1] * srcData[10] * srcData[15]+
543        srcData[0] * srcData[5] * srcData[10] * srcData[15];
544
545    if ( det == 0.0f ) return;
546    det = 1 / det;
547
548    _data[0] = (srcData[9]*srcData[14]*srcData[7] -
549                srcData[13]*srcData[10]*srcData[7] +
550                srcData[13]*srcData[6]*srcData[11] -
551                srcData[5]*srcData[14]*srcData[11] -
552                srcData[9]*srcData[6]*srcData[15] +
553                srcData[5]*srcData[10]*srcData[15]) * det;
554
555    _data[4] = (srcData[12]*srcData[10]*srcData[7] -
556                srcData[8]*srcData[14]*srcData[7] -
557                srcData[12]*srcData[6]*srcData[11] +
558                srcData[4]*srcData[14]*srcData[11] +
559                srcData[8]*srcData[6]*srcData[15] -
560                srcData[4]*srcData[10]*srcData[15]) * det;
561
562    _data[8] = (srcData[8]*srcData[13]*srcData[7] -
563                srcData[12]*srcData[9]*srcData[7] +
564                srcData[12]*srcData[5]*srcData[11] -
565                srcData[4]*srcData[13]*srcData[11] -
566                srcData[8]*srcData[5]*srcData[15] +
567                srcData[4]*srcData[9]*srcData[15]) * det;
568
569    _data[12] = (srcData[12]*srcData[9]*srcData[6] -
570                 srcData[8]*srcData[13]*srcData[6] -
571                 srcData[12]*srcData[5]*srcData[10] +
572                 srcData[4]*srcData[13]*srcData[10] +
573                 srcData[8]*srcData[5]*srcData[14] -
574                 srcData[4]*srcData[9]*srcData[14]) * det;
575
576    _data[1] = (srcData[13]*srcData[10]*srcData[3] -
577                srcData[9]*srcData[14]*srcData[3] -
578                srcData[13]*srcData[2]*srcData[11] +
579                srcData[1]*srcData[14]*srcData[11] +
580                srcData[9]*srcData[2]*srcData[15] -
581                srcData[1]*srcData[10]*srcData[15]) * det;
582
583    _data[5] = (srcData[8]*srcData[14]*srcData[3] -
584                srcData[12]*srcData[10]*srcData[3] +
585                srcData[12]*srcData[2]*srcData[11] -
586                srcData[0]*srcData[14]*srcData[11] -
587                srcData[8]*srcData[2]*srcData[15] +
588                srcData[0]*srcData[10]*srcData[15]) * det;
589
590    _data[9] = (srcData[12]*srcData[9]*srcData[3] -
591                srcData[8]*srcData[13]*srcData[3] -
592                srcData[12]*srcData[1]*srcData[11] +
593                srcData[0]*srcData[13]*srcData[11] +
594                srcData[8]*srcData[1]*srcData[15] -
595                srcData[0]*srcData[9]*srcData[15]) * det;
596
597    _data[13] = (srcData[8]*srcData[13]*srcData[2] -
598                 srcData[12]*srcData[9]*srcData[2] +
599                 srcData[12]*srcData[1]*srcData[10] -
600                 srcData[0]*srcData[13]*srcData[10] -
601                 srcData[8]*srcData[1]*srcData[14] +
602                 srcData[0]*srcData[9]*srcData[14]) * det;
603
604    _data[2] = (srcData[5]*srcData[14]*srcData[3] -
605                srcData[13]*srcData[6]*srcData[3] +
606                srcData[13]*srcData[2]*srcData[7] -
607                srcData[1]*srcData[14]*srcData[7] -
608                srcData[5]*srcData[2]*srcData[15] +
609                srcData[1]*srcData[6]*srcData[15]) * det;
610
611    _data[6] = (srcData[12]*srcData[6]*srcData[3] -
612                srcData[4]*srcData[14]*srcData[3] -
613                srcData[12]*srcData[2]*srcData[7] +
614                srcData[0]*srcData[14]*srcData[7] +
615                srcData[4]*srcData[2]*srcData[15] -
616                srcData[0]*srcData[6]*srcData[15]) * det;
617
618    _data[10] = (srcData[4]*srcData[13]*srcData[3] -
619                 srcData[12]*srcData[5]*srcData[3] +
620                 srcData[12]*srcData[1]*srcData[7] -
621                 srcData[0]*srcData[13]*srcData[7] -
622                 srcData[4]*srcData[1]*srcData[15] +
623                 srcData[0]*srcData[5]*srcData[15]) * det;
624
625    _data[14] = (srcData[12]*srcData[5]*srcData[2] -
626                 srcData[4]*srcData[13]*srcData[2] -
627                 srcData[12]*srcData[1]*srcData[6] +
628                 srcData[0]*srcData[13]*srcData[6] +
629                 srcData[4]*srcData[1]*srcData[14] -
630                 srcData[0]*srcData[5]*srcData[14]) * det;
631
632    _data[3] = (srcData[9]*srcData[6]*srcData[3] -
633                srcData[5]*srcData[10]*srcData[3] -
634                srcData[9]*srcData[2]*srcData[7] +
635                srcData[1]*srcData[10]*srcData[7] +
636                srcData[5]*srcData[2]*srcData[11] -
637                srcData[1]*srcData[6]*srcData[11]) * det;
638
639    _data[7] = (srcData[4]*srcData[10]*srcData[3] -
640                srcData[8]*srcData[6]*srcData[3] +
641                srcData[8]*srcData[2]*srcData[7] -
642                srcData[0]*srcData[10]*srcData[7] -
643                srcData[4]*srcData[2]*srcData[11] +
644                srcData[0]*srcData[6]*srcData[11]) * det;
645
646    _data[11] = (srcData[8]*srcData[5]*srcData[3] -
647                 srcData[4]*srcData[9]*srcData[3] -
648                 srcData[8]*srcData[1]*srcData[7] +
649                 srcData[0]*srcData[9]*srcData[7] +
650                 srcData[4]*srcData[1]*srcData[11] -
651                 srcData[0]*srcData[5]*srcData[11]) * det;
652
653    _data[15] = (srcData[4]*srcData[9]*srcData[2] -
654                 srcData[8]*srcData[5]*srcData[2] +
655                 srcData[8]*srcData[1]*srcData[6] -
656                 srcData[0]*srcData[9]*srcData[6] -
657                 srcData[4]*srcData[1]*srcData[10] +
658                 srcData[0]*srcData[5]*srcData[10]) * det;
659}
660
661void Matrix4x4f::transpose()
662{
663    float m[16];
664
665    m[0] = _data[0];
666    m[1] = _data[4];
667    m[2] = _data[8];
668    m[3] = _data[12];
669
670    m[4] = _data[1];
671    m[5] = _data[5];
672    m[6] = _data[9];
673    m[7] = _data[13];
674
675    m[8] = _data[2];
676    m[9] = _data[6];
677    m[10] = _data[10];
678    m[11] = _data[14];
679
680    m[12] = _data[3];
681    m[13] = _data[7];
682    m[14] = _data[11];
683    m[15] = _data[15];
684
685    set(m);
686}
687
688void Matrix4x4f::transposeFast(const Matrix4x4f& mat)
689{
690    _data[0] = mat._data[0];
691    _data[1] = mat._data[4];
692    _data[2] = mat._data[8];
693    _data[3] = mat._data[12];
694
695    _data[4] = mat._data[1];
696    _data[5] = mat._data[5];
697    _data[6] = mat._data[9];
698    _data[7] = mat._data[13];
699
700    _data[8] = mat._data[2];
701    _data[9] = mat._data[6];
702    _data[10] = mat._data[10];
703    _data[11] = mat._data[14];
704
705    _data[12] = mat._data[3];
706    _data[13] = mat._data[7];
707    _data[14] = mat._data[11];
708    _data[15] = mat._data[15];
709}
710
711void Matrix4x4f::transpose(const Matrix4x4f& mat)
712{
713    if (&mat == this) {
714        transpose();
715    } else {
716        transposeFast(mat);
717    }
718}
719
720void Matrix4x4f::setDouble(const double *m)
721{
722    for (int i = 0; i < 16; ++i) {
723        _data[i] = (float)m[i];
724    }
725}
726
727void Matrix4x4f::multiply(const Matrix4x4f& mat1, const Vector3f& position)
728{
729    Matrix4x4f mat;
730    mat.makeTranslation(position);
731    multiply(mat1, mat);
732}
733
734void Matrix4x4f::multiply(const Matrix4x4f& mat1, const Rotation& rotation)
735{
736    Matrix4x4f mat;
737    mat.makeRotation(rotation);
738    multiply(mat1, mat);
739}
740
741void Matrix4x4f::multiply(const Vector3f& position, const Matrix4x4f& mat1)
742{
743    Matrix4x4f mat;
744    mat.makeTranslation(position);
745    multiply(mat, mat1);
746}
747
748void Matrix4x4f::multiply(const Rotation& rotation, const Matrix4x4f& mat1)
749{
750    Matrix4x4f mat;
751    mat.makeRotation(rotation);
752    multiply(mat, mat1);
753}
754
755void Matrix4x4f::makeVecRotVec(const Vector3f& vec1, const Vector3f& vec2)
756{
757    Vector3f axis = cross(vec1, vec2);
758
759    float angle = atan2(axis.length(), vec1.dot(vec2));
760    axis = axis.normalize();
761    makeRotation(axis.x, axis.y, axis.z, angle);
762}
763
764void Matrix4x4f::multiplyScale(const Matrix4x4f& mat1, const Vector3f& scale)
765{
766    Matrix4x4f mat;
767    mat.makeScale(scale);
768    multiply(mat1, mat);
769}
770
771void Matrix4x4f::multiplyScale(const Vector3f& scale, const Matrix4x4f& mat1)
772{
773    Matrix4x4f mat;
774    mat.makeScale(scale);
775    multiply(mat, mat1);
776}
Note: See TracBrowser for help on using the repository browser.