source: nanovis/trunk/vrmath/Matrix4x4d.cpp @ 5048

Last change on this file since 5048 was 3630, checked in by ldelgass, 12 years ago

Nanovis refactoring to fix problems with scaling and multiple results.
Do rendering in world space to properly place and scale multiple data sets.
Also fix flows to reduce resets of animations. More work toward removing
Cg dependency. Fix panning to convert viewport coords to world coords.

  • Property svn:eol-style set to native
File size: 29.6 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/Matrix4x4d.h>
10#include <vrmath/Vector3f.h>
11#include <vrmath/Rotation.h>
12
13using namespace vrmath;
14
15void Matrix4x4d::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.0;
20    _data[0] = _data[5] = _data[10] = _data[15] = 1.0;
21}
22
23void Matrix4x4d::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.0;
28    _data[0] = _data[5] = _data[10] = _data[15] = 1.0;
29    _data[12] = translation.x;
30    _data[13] = translation.y;
31    _data[14] = translation.z;
32}
33
34void Matrix4x4d::makeTranslation(double x, double y, double z)
35{
36    _data[1] = _data[2] = _data[3] = _data[4] =
37        _data[6] = _data[7] = _data[8] = _data[9] =
38        _data[11] = 0.0;
39    _data[0] = _data[5] = _data[10] = _data[15] = 1.0;
40    _data[12] = x;
41    _data[13] = y;
42    _data[14] = z;
43}
44
45void Matrix4x4d::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.0;
69    _data[15] = 1.0;
70
71    _data[0] = xAxis * xAxis * oneMinusCosine + cosine;
72    _data[1] = yAxis * xAxis * oneMinusCosine + zAxis * sine;
73    _data[2] = xAxis * zAxis * oneMinusCosine - yAxis * sine;
74
75    _data[4] = xAxis * yAxis * oneMinusCosine - zAxis * sine;
76    _data[5] = yAxis * yAxis * oneMinusCosine + cosine;
77    _data[6] = yAxis * zAxis * oneMinusCosine + xAxis * sine;
78
79    _data[8] = xAxis * zAxis * oneMinusCosine + yAxis * sine;
80    _data[9] = yAxis * zAxis * oneMinusCosine - xAxis * sine;
81    _data[10] = zAxis * zAxis * oneMinusCosine + cosine;
82}
83
84void Matrix4x4d::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.0f / sqrt(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis);
95    double cosine = cos(angle);
96    double sine = sin(angle);
97
98    xAxis *= invLen;
99    yAxis *= invLen;
100    zAxis *= invLen;
101
102    float oneMinusCosine = 1.0 - cosine;
103
104    _data[3] = _data[7] = _data[11] = _data[12] = _data[13] = _data[14] = 0.0;
105    _data[15] = 1.0;
106
107    _data[0] = xAxis * xAxis * oneMinusCosine + cosine;
108    _data[1] = yAxis * xAxis * oneMinusCosine + zAxis * sine;
109    _data[2] = xAxis * zAxis * oneMinusCosine - yAxis * sine;
110
111    _data[4] = xAxis * yAxis * oneMinusCosine - zAxis * sine;
112    _data[5] = yAxis * yAxis * oneMinusCosine + cosine;
113    _data[6] = yAxis * zAxis * oneMinusCosine + xAxis * sine;
114
115    _data[8] = xAxis * zAxis * oneMinusCosine + yAxis * sine;
116    _data[9] = yAxis * zAxis * oneMinusCosine - xAxis * sine;
117    _data[10] = zAxis * zAxis * oneMinusCosine + cosine;
118}
119
120void Matrix4x4d::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 Matrix4x4d::makeScale(double x, double y, double 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
149Matrix4x4d::transform(const Vector4f& v) const
150{
151    Vector4f ret;
152    ret.x = float(_data[0] * v.x + _data[4] * v.y + _data[8] * v.z  + _data[12] * v.w);
153    ret.y = float(_data[1] * v.x + _data[5] * v.y + _data[9] * v.z  + _data[13] * v.w);
154    ret.z = float(_data[2] * v.x + _data[6] * v.y + _data[10] * v.z + _data[14] * v.w);
155    ret.w = float(_data[3] * v.x + _data[7] * v.y + _data[11] * v.z + _data[15] * v.w);
156    return ret;
157}
158
159Vector3f
160Matrix4x4d::transformVec(const Vector3f& v) const
161{
162    Vector3f ret;
163    ret.x = float(_data[0] * v.x + _data[4] * v.y + _data[8] * v.z);
164    ret.y = float(_data[1] * v.x + _data[5] * v.y + _data[9] * v.z);
165    ret.z = float(_data[2] * v.x + _data[6] * v.y + _data[10] * v.z);
166    return ret;
167}
168
169Vector4f
170Matrix4x4d::preMultiplyRowVector(const Vector4f& v) const
171{
172    Vector4f ret;
173    ret.x = float(_data[0]  * v.x + _data[1]  * v.y + _data[2]  * v.z + _data[3]  * v.w);
174    ret.y = float(_data[4]  * v.x + _data[5]  * v.y + _data[6]  * v.z + _data[7]  * v.w);
175    ret.z = float(_data[8]  * v.x + _data[9]  * v.y + _data[10] * v.z + _data[11] * v.w);
176    ret.w = float(_data[12] * v.x + _data[13] * v.y + _data[14] * v.z + _data[15] * v.w);
177    return ret;
178}
179
180void Matrix4x4d::multiply(const Matrix4x4d& m)
181{
182    double mat[16];
183    const double *mat2 = m._data;
184
185    // 1 row
186    mat[0] = _data[0] * mat2[0] + _data[4] * mat2[1] +
187             _data[8] * mat2[2] + _data[12] * mat2[3];
188    mat[4] = _data[0] * mat2[4] + _data[4] * mat2[5] +
189             _data[8] * mat2[6] + _data[12] * mat2[7];
190    mat[8] = _data[0] * mat2[8] + _data[4] * mat2[9] +
191             _data[8] * mat2[10] + _data[12] * mat2[11];
192    mat[12] = _data[0] * mat2[12] + _data[4] * mat2[13] +
193              _data[8] * mat2[14] + _data[12] * mat2[15];
194
195    // 2 row
196    mat[1] = _data[1] * mat2[0] + _data[5] * mat2[1] +
197             _data[9] * mat2[2] + _data[13] * mat2[3];
198    mat[5] = _data[1] * mat2[4] + _data[5] * mat2[5] +
199             _data[9] * mat2[6] + _data[13] * mat2[7];
200    mat[9] = _data[1] * mat2[8] + _data[5] * mat2[9] +
201             _data[9] * mat2[10] + _data[13] * mat2[11];
202    mat[13] = _data[1] * mat2[12] + _data[5] * mat2[13] +
203              _data[9] * mat2[14] + _data[13] * mat2[15];
204
205    // 3 row
206    mat[2] = _data[2] * mat2[0] + _data[6] * mat2[1] +
207             _data[10] * mat2[2] + _data[14] * mat2[3];
208    mat[6] = _data[2] * mat2[4] + _data[6] * mat2[5] +
209             _data[10] * mat2[6] + _data[14] * mat2[7];
210    mat[10] = _data[2] * mat2[8] + _data[6] * mat2[9] +
211              _data[10] * mat2[10] + _data[14] * mat2[11];
212    mat[14] = _data[2] * mat2[12] + _data[6] * mat2[13] +
213              _data[10] * mat2[14] + _data[14] * mat2[15];
214
215    // 4 row
216    mat[3] = _data[3] * mat2[0] + _data[7] * mat2[1] +
217             _data[11] * mat2[2] + _data[15] * mat2[3];
218    mat[7] = _data[3] * mat2[4] + _data[7] * mat2[5] +
219             _data[11] * mat2[6] + _data[15] * mat2[7];
220    mat[11] = _data[3] * mat2[8] + _data[7] * mat2[9] +
221              _data[11] * mat2[10] + _data[15] * mat2[11];
222    mat[15] = _data[3] * mat2[12] + _data[7] * mat2[13] +
223              _data[11] * mat2[14] + _data[15] * mat2[15];
224
225    // set matrix
226    set(mat);
227}
228
229void Matrix4x4d::multiply(const Matrix4x4d& m1, const Matrix4x4d& m2)
230{
231    if (&m1 == this && &m2 != this) {
232        multiply(m2);
233    } else if (&m1 != this && &m2 != this) {
234        multiplyFast(m1, m2);
235    } else {
236        double mat[16];
237        const double *mat1 = m1._data;
238        const double *mat2 = m2._data;
239
240        // 1 row
241        mat[0] = mat1[0] * mat2[0] + mat1[4] * mat2[1] +
242            mat1[8] * mat2[2] + mat1[12] * mat2[3];
243        mat[4] = mat1[0] * mat2[4] + mat1[4] * mat2[5] +
244            mat1[8] * mat2[6] + mat1[12] * mat2[7];
245        mat[8] = mat1[0] * mat2[8] + mat1[4] * mat2[9] +
246            mat1[8] * mat2[10] + mat1[12] * mat2[11];
247        mat[12] = mat1[0] * mat2[12] + mat1[4] * mat2[13] +
248            mat1[8] * mat2[14] + mat1[12] * mat2[15];
249
250        // 2 row
251        mat[1] = mat1[1] * mat2[0] + mat1[5] * mat2[1] +
252            mat1[9] * mat2[2] + mat1[13] * mat2[3];
253        mat[5] = mat1[1] * mat2[4] + mat1[5] * mat2[5] +
254            mat1[9] * mat2[6] + mat1[13] * mat2[7];
255        mat[9] = mat1[1] * mat2[8] + mat1[5] * mat2[9] +
256            mat1[9] * mat2[10] + mat1[13] * mat2[11];
257        mat[13] = mat1[1] * mat2[12] + mat1[5] * mat2[13] +
258            mat1[9] * mat2[14] + mat1[13] * mat2[15];
259
260        // 3 row
261        mat[2] = mat1[2] * mat2[0] + mat1[6] * mat2[1] +
262            mat1[10] * mat2[2] + mat1[14] * mat2[3];
263        mat[6] = mat1[2] * mat2[4] + mat1[6] * mat2[5] +
264            mat1[10] * mat2[6] + mat1[14] * mat2[7];
265        mat[10] = mat1[2] * mat2[8] + mat1[6] * mat2[9] +
266            mat1[10] * mat2[10] + mat1[14] * mat2[11];
267        mat[14] = mat1[2] * mat2[12] + mat1[6] * mat2[13] +
268            mat1[10] * mat2[14] + mat1[14] * mat2[15];
269
270        // 4 row
271        mat[3] = mat1[3] * mat2[0] + mat1[7] * mat2[1] +
272            mat1[11] * mat2[2] + mat1[15] * mat2[3];
273        mat[7] = mat1[3] * mat2[4] + mat1[7] * mat2[5] +
274            mat1[11] * mat2[6] + mat1[15] * mat2[7];
275        mat[11] = mat1[3] * mat2[8] + mat1[7] * mat2[9] +
276            mat1[11] * mat2[10] + mat1[15] * mat2[11];
277        mat[15] = mat1[3] * mat2[12] + mat1[7] * mat2[13] +
278            mat1[11] * mat2[14] + mat1[15] * mat2[15];
279
280        // set matrix
281        set(mat);
282    }
283}
284
285void Matrix4x4d::multiplyFast(const Matrix4x4d& m1, const Matrix4x4d& m2)
286{
287    const double *mat1 = m1._data;
288    const double *mat2 = m2._data;
289
290    // 1 row
291    _data[0] = mat1[0] * mat2[0] + mat1[4] * mat2[1] +
292               mat1[8] * mat2[2] + mat1[12] * mat2[3];
293    _data[4] = mat1[0] * mat2[4] + mat1[4] * mat2[5] +
294               mat1[8] * mat2[6] + mat1[12] * mat2[7];
295    _data[8] = mat1[0] * mat2[8] + mat1[4] * mat2[9] +
296               mat1[8] * mat2[10] + mat1[12] * mat2[11];
297    _data[12] = mat1[0] * mat2[12] + mat1[4] * mat2[13] +
298                mat1[8] * mat2[14] + mat1[12] * mat2[15];
299
300    // 2 row
301    _data[1] = mat1[1] * mat2[0] + mat1[5] * mat2[1] +
302               mat1[9] * mat2[2] + mat1[13] * mat2[3];
303    _data[5] = mat1[1] * mat2[4] + mat1[5] * mat2[5] +
304               mat1[9] * mat2[6] + mat1[13] * mat2[7];
305    _data[9] = mat1[1] * mat2[8] + mat1[5] * mat2[9] +
306               mat1[9] * mat2[10] + mat1[13] * mat2[11];
307    _data[13] = mat1[1] * mat2[12] + mat1[5] * mat2[13] +
308                mat1[9] * mat2[14] + mat1[13] * mat2[15];
309
310    // 3 row
311    _data[2] = mat1[2] * mat2[0] + mat1[6] * mat2[1] +
312               mat1[10] * mat2[2] + mat1[14] * mat2[3];
313    _data[6] = mat1[2] * mat2[4] + mat1[6] * mat2[5] +
314               mat1[10] * mat2[6] + mat1[14] * mat2[7];
315    _data[10] = mat1[2] * mat2[8] + mat1[6] * mat2[9] +
316                mat1[10] * mat2[10] + mat1[14] * mat2[11];
317    _data[14] = mat1[2] * mat2[12] + mat1[6] * mat2[13] +
318                mat1[10] * mat2[14] + mat1[14] * mat2[15];
319
320    // 4 row
321    _data[3] = mat1[3] * mat2[0] + mat1[7] * mat2[1] +
322               mat1[11] * mat2[2] + mat1[15] * mat2[3];
323    _data[7] = mat1[3] * mat2[4] + mat1[7] * mat2[5] +
324               mat1[11] * mat2[6] + mat1[15] * mat2[7];
325    _data[11] = mat1[3] * mat2[8] + mat1[7] * mat2[9] +
326                mat1[11] * mat2[10] + mat1[15] * mat2[11];
327    _data[15] = mat1[3] * mat2[12] + mat1[7] * mat2[13] +
328                mat1[11] * mat2[14] + mat1[15] * mat2[15];
329}
330
331void Matrix4x4d::getRotation(Rotation& rotation)
332{
333    double c = (_data[0] + _data[5] + _data[10] - 1.0) * 0.5;
334
335    rotation.setAxis(_data[6] - _data[9], _data[8] - _data[2], _data[1] - _data[4]);
336
337    double len = sqrt(rotation.getX() * rotation.getX() +
338                      rotation.getY() * rotation.getY() +
339                      rotation.getZ() * rotation.getZ());
340
341    double s = 0.5 * len;
342
343    rotation.setAngle(atan2(s, c));
344
345    if (rotation.getX() == 0.0 &&
346        rotation.getY() == 0.0 &&
347        rotation.getZ() == 0.0) {
348        rotation.set(0, 1, 0, 0);
349    } else {
350        len = 1.0 / len;
351        rotation.setAxis(rotation.getX() * len,
352                         rotation.getY() * len,
353                         rotation.getZ() * len);
354    }
355}
356
357void Matrix4x4d::invert()
358{
359    double det =
360        _data[12] * _data[9] * _data[6] * _data[3]-
361        _data[8] * _data[13] * _data[6] * _data[3]-
362        _data[12] * _data[5] * _data[10] * _data[3]+
363        _data[4] * _data[13] * _data[10] * _data[3]+
364        _data[8] * _data[5] * _data[14] * _data[3]-
365        _data[4] * _data[9] * _data[14] * _data[3]-
366        _data[12] * _data[9] * _data[2] * _data[7]+
367        _data[8] * _data[13] * _data[2] * _data[7]+
368        _data[12] * _data[1] * _data[10] * _data[7]-
369        _data[0] * _data[13] * _data[10] * _data[7]-
370        _data[8] * _data[1] * _data[14] * _data[7]+
371        _data[0] * _data[9] * _data[14] * _data[7]+
372        _data[12] * _data[5] * _data[2] * _data[11]-
373        _data[4] * _data[13] * _data[2] * _data[11]-
374        _data[12] * _data[1] * _data[6] * _data[11]+
375        _data[0] * _data[13] * _data[6] * _data[11]+
376        _data[4] * _data[1] * _data[14] * _data[11]-
377        _data[0] * _data[5] * _data[14] * _data[11]-
378        _data[8] * _data[5] * _data[2] * _data[15]+
379        _data[4] * _data[9] * _data[2] * _data[15]+
380        _data[8] * _data[1] * _data[6] * _data[15]-
381        _data[0] * _data[9] * _data[6] * _data[15]-
382        _data[4] * _data[1] * _data[10] * _data[15]+
383        _data[0] * _data[5] * _data[10] * _data[15];
384
385    if ( det == 0.0 ) return;
386    det = 1.0 / det;
387
388    double mat[16];
389
390    mat[0] = (_data[9]*_data[14]*_data[7] -
391              _data[13]*_data[10]*_data[7] +
392              _data[13]*_data[6]*_data[11] -
393              _data[5]*_data[14]*_data[11] -
394              _data[9]*_data[6]*_data[15] +
395              _data[5]*_data[10]*_data[15]) * det;
396
397    mat[4] = (_data[12]*_data[10]*_data[7] -
398              _data[8]*_data[14]*_data[7] -
399              _data[12]*_data[6]*_data[11] +
400              _data[4]*_data[14]*_data[11] +
401              _data[8]*_data[6]*_data[15] -
402              _data[4]*_data[10]*_data[15]) * det;
403
404    mat[8] = (_data[8]*_data[13]*_data[7] -
405              _data[12]*_data[9]*_data[7] +
406              _data[12]*_data[5]*_data[11] -
407              _data[4]*_data[13]*_data[11] -
408              _data[8]*_data[5]*_data[15] +
409              _data[4]*_data[9]*_data[15]) * det;
410
411    mat[12] = (_data[12]*_data[9]*_data[6] -
412               _data[8]*_data[13]*_data[6] -
413               _data[12]*_data[5]*_data[10] +
414               _data[4]*_data[13]*_data[10] +
415               _data[8]*_data[5]*_data[14] -
416               _data[4]*_data[9]*_data[14]) * det;
417
418    mat[1] = (_data[13]*_data[10]*_data[3] -
419              _data[9]*_data[14]*_data[3] -
420              _data[13]*_data[2]*_data[11] +
421              _data[1]*_data[14]*_data[11] +
422              _data[9]*_data[2]*_data[15] -
423              _data[1]*_data[10]*_data[15]) * det;
424
425    mat[5] = (_data[8]*_data[14]*_data[3] -
426              _data[12]*_data[10]*_data[3] +
427              _data[12]*_data[2]*_data[11] -
428              _data[0]*_data[14]*_data[11] -
429              _data[8]*_data[2]*_data[15] +
430              _data[0]*_data[10]*_data[15]) * det;
431
432    mat[9] = (_data[12]*_data[9]*_data[3] -
433              _data[8]*_data[13]*_data[3] -
434              _data[12]*_data[1]*_data[11] +
435              _data[0]*_data[13]*_data[11] +
436              _data[8]*_data[1]*_data[15] -
437              _data[0]*_data[9]*_data[15]) * det;
438
439    mat[13] = (_data[8]*_data[13]*_data[2] -
440               _data[12]*_data[9]*_data[2] +
441               _data[12]*_data[1]*_data[10] -
442               _data[0]*_data[13]*_data[10] -
443               _data[8]*_data[1]*_data[14] +
444               _data[0]*_data[9]*_data[14]) * det;
445
446    mat[2] = (_data[5]*_data[14]*_data[3] -
447              _data[13]*_data[6]*_data[3] +
448              _data[13]*_data[2]*_data[7] -
449              _data[1]*_data[14]*_data[7] -
450              _data[5]*_data[2]*_data[15] +
451              _data[1]*_data[6]*_data[15]) * det;
452
453    mat[6] = (_data[12]*_data[6]*_data[3] -
454              _data[4]*_data[14]*_data[3] -
455              _data[12]*_data[2]*_data[7] +
456              _data[0]*_data[14]*_data[7] +
457              _data[4]*_data[2]*_data[15] -
458              _data[0]*_data[6]*_data[15]) * det;
459
460    mat[10] = (_data[4]*_data[13]*_data[3] -
461               _data[12]*_data[5]*_data[3] +
462               _data[12]*_data[1]*_data[7] -
463               _data[0]*_data[13]*_data[7] -
464               _data[4]*_data[1]*_data[15] +
465               _data[0]*_data[5]*_data[15]) * det;
466
467    mat[14] = (_data[12]*_data[5]*_data[2] -
468               _data[4]*_data[13]*_data[2] -
469               _data[12]*_data[1]*_data[6] +
470               _data[0]*_data[13]*_data[6] +
471               _data[4]*_data[1]*_data[14] -
472               _data[0]*_data[5]*_data[14]) * det;
473
474    mat[3] = (_data[9]*_data[6]*_data[3] -
475              _data[5]*_data[10]*_data[3] -
476              _data[9]*_data[2]*_data[7] +
477              _data[1]*_data[10]*_data[7] +
478              _data[5]*_data[2]*_data[11] -
479              _data[1]*_data[6]*_data[11]) * det;
480
481    mat[7] = (_data[4]*_data[10]*_data[3] -
482              _data[8]*_data[6]*_data[3] +
483              _data[8]*_data[2]*_data[7] -
484              _data[0]*_data[10]*_data[7] -
485              _data[4]*_data[2]*_data[11] +
486              _data[0]*_data[6]*_data[11]) * det;
487
488    mat[11] = (_data[8]*_data[5]*_data[3] -
489               _data[4]*_data[9]*_data[3] -
490               _data[8]*_data[1]*_data[7] +
491               _data[0]*_data[9]*_data[7] +
492               _data[4]*_data[1]*_data[11] -
493               _data[0]*_data[5]*_data[11]) * det;
494
495    mat[15] = (_data[4]*_data[9]*_data[2] -
496               _data[8]*_data[5]*_data[2] +
497               _data[8]*_data[1]*_data[6] -
498               _data[0]*_data[9]*_data[6] -
499               _data[4]*_data[1]*_data[10] +
500               _data[0]*_data[5]*_data[10]) * det;
501
502    set(mat);
503}
504
505void Matrix4x4d::invert(const Matrix4x4d& mat)
506{
507    if (&mat == this) {
508        invert();
509    } else {
510        invertFast(mat);
511    }
512}
513
514void Matrix4x4d::invertFast(const Matrix4x4d& mat)
515{
516    const double *srcData = mat._data;
517
518    double det =
519        srcData[12] * srcData[9] * srcData[6] * srcData[3]-
520        srcData[8] * srcData[13] * srcData[6] * srcData[3]-
521        srcData[12] * srcData[5] * srcData[10] * srcData[3]+
522        srcData[4] * srcData[13] * srcData[10] * srcData[3]+
523        srcData[8] * srcData[5] * srcData[14] * srcData[3]-
524        srcData[4] * srcData[9] * srcData[14] * srcData[3]-
525        srcData[12] * srcData[9] * srcData[2] * srcData[7]+
526        srcData[8] * srcData[13] * srcData[2] * srcData[7]+
527        srcData[12] * srcData[1] * srcData[10] * srcData[7]-
528        srcData[0] * srcData[13] * srcData[10] * srcData[7]-
529        srcData[8] * srcData[1] * srcData[14] * srcData[7]+
530        srcData[0] * srcData[9] * srcData[14] * srcData[7]+
531        srcData[12] * srcData[5] * srcData[2] * srcData[11]-
532        srcData[4] * srcData[13] * srcData[2] * srcData[11]-
533        srcData[12] * srcData[1] * srcData[6] * srcData[11]+
534        srcData[0] * srcData[13] * srcData[6] * srcData[11]+
535        srcData[4] * srcData[1] * srcData[14] * srcData[11]-
536        srcData[0] * srcData[5] * srcData[14] * srcData[11]-
537        srcData[8] * srcData[5] * srcData[2] * srcData[15]+
538        srcData[4] * srcData[9] * srcData[2] * srcData[15]+
539        srcData[8] * srcData[1] * srcData[6] * srcData[15]-
540        srcData[0] * srcData[9] * srcData[6] * srcData[15]-
541        srcData[4] * srcData[1] * srcData[10] * srcData[15]+
542        srcData[0] * srcData[5] * srcData[10] * srcData[15];
543
544    if ( det == 0.0 ) return;
545    det = 1.0 / det;
546
547    _data[0] = (srcData[9]*srcData[14]*srcData[7] -
548                srcData[13]*srcData[10]*srcData[7] +
549                srcData[13]*srcData[6]*srcData[11] -
550                srcData[5]*srcData[14]*srcData[11] -
551                srcData[9]*srcData[6]*srcData[15] +
552                srcData[5]*srcData[10]*srcData[15]) * det;
553
554    _data[4] = (srcData[12]*srcData[10]*srcData[7] -
555                srcData[8]*srcData[14]*srcData[7] -
556                srcData[12]*srcData[6]*srcData[11] +
557                srcData[4]*srcData[14]*srcData[11] +
558                srcData[8]*srcData[6]*srcData[15] -
559                srcData[4]*srcData[10]*srcData[15]) * det;
560
561    _data[8] = (srcData[8]*srcData[13]*srcData[7] -
562                srcData[12]*srcData[9]*srcData[7] +
563                srcData[12]*srcData[5]*srcData[11] -
564                srcData[4]*srcData[13]*srcData[11] -
565                srcData[8]*srcData[5]*srcData[15] +
566                srcData[4]*srcData[9]*srcData[15]) * det;
567
568    _data[12] = (srcData[12]*srcData[9]*srcData[6] -
569                 srcData[8]*srcData[13]*srcData[6] -
570                 srcData[12]*srcData[5]*srcData[10] +
571                 srcData[4]*srcData[13]*srcData[10] +
572                 srcData[8]*srcData[5]*srcData[14] -
573                 srcData[4]*srcData[9]*srcData[14]) * det;
574
575    _data[1] = (srcData[13]*srcData[10]*srcData[3] -
576                srcData[9]*srcData[14]*srcData[3] -
577                srcData[13]*srcData[2]*srcData[11] +
578                srcData[1]*srcData[14]*srcData[11] +
579                srcData[9]*srcData[2]*srcData[15] -
580                srcData[1]*srcData[10]*srcData[15]) * det;
581
582    _data[5] = (srcData[8]*srcData[14]*srcData[3] -
583                srcData[12]*srcData[10]*srcData[3] +
584                srcData[12]*srcData[2]*srcData[11] -
585                srcData[0]*srcData[14]*srcData[11] -
586                srcData[8]*srcData[2]*srcData[15] +
587                srcData[0]*srcData[10]*srcData[15]) * det;
588
589    _data[9] = (srcData[12]*srcData[9]*srcData[3] -
590                srcData[8]*srcData[13]*srcData[3] -
591                srcData[12]*srcData[1]*srcData[11] +
592                srcData[0]*srcData[13]*srcData[11] +
593                srcData[8]*srcData[1]*srcData[15] -
594                srcData[0]*srcData[9]*srcData[15]) * det;
595
596    _data[13] = (srcData[8]*srcData[13]*srcData[2] -
597                 srcData[12]*srcData[9]*srcData[2] +
598                 srcData[12]*srcData[1]*srcData[10] -
599                 srcData[0]*srcData[13]*srcData[10] -
600                 srcData[8]*srcData[1]*srcData[14] +
601                 srcData[0]*srcData[9]*srcData[14]) * det;
602
603    _data[2] = (srcData[5]*srcData[14]*srcData[3] -
604                srcData[13]*srcData[6]*srcData[3] +
605                srcData[13]*srcData[2]*srcData[7] -
606                srcData[1]*srcData[14]*srcData[7] -
607                srcData[5]*srcData[2]*srcData[15] +
608                srcData[1]*srcData[6]*srcData[15]) * det;
609
610    _data[6] = (srcData[12]*srcData[6]*srcData[3] -
611                srcData[4]*srcData[14]*srcData[3] -
612                srcData[12]*srcData[2]*srcData[7] +
613                srcData[0]*srcData[14]*srcData[7] +
614                srcData[4]*srcData[2]*srcData[15] -
615                srcData[0]*srcData[6]*srcData[15]) * det;
616
617    _data[10] = (srcData[4]*srcData[13]*srcData[3] -
618                 srcData[12]*srcData[5]*srcData[3] +
619                 srcData[12]*srcData[1]*srcData[7] -
620                 srcData[0]*srcData[13]*srcData[7] -
621                 srcData[4]*srcData[1]*srcData[15] +
622                 srcData[0]*srcData[5]*srcData[15]) * det;
623
624    _data[14] = (srcData[12]*srcData[5]*srcData[2] -
625                 srcData[4]*srcData[13]*srcData[2] -
626                 srcData[12]*srcData[1]*srcData[6] +
627                 srcData[0]*srcData[13]*srcData[6] +
628                 srcData[4]*srcData[1]*srcData[14] -
629                 srcData[0]*srcData[5]*srcData[14]) * det;
630
631    _data[3] = (srcData[9]*srcData[6]*srcData[3] -
632                srcData[5]*srcData[10]*srcData[3] -
633                srcData[9]*srcData[2]*srcData[7] +
634                srcData[1]*srcData[10]*srcData[7] +
635                srcData[5]*srcData[2]*srcData[11] -
636                srcData[1]*srcData[6]*srcData[11]) * det;
637
638    _data[7] = (srcData[4]*srcData[10]*srcData[3] -
639                srcData[8]*srcData[6]*srcData[3] +
640                srcData[8]*srcData[2]*srcData[7] -
641                srcData[0]*srcData[10]*srcData[7] -
642                srcData[4]*srcData[2]*srcData[11] +
643                srcData[0]*srcData[6]*srcData[11]) * det;
644
645    _data[11] = (srcData[8]*srcData[5]*srcData[3] -
646                 srcData[4]*srcData[9]*srcData[3] -
647                 srcData[8]*srcData[1]*srcData[7] +
648                 srcData[0]*srcData[9]*srcData[7] +
649                 srcData[4]*srcData[1]*srcData[11] -
650                 srcData[0]*srcData[5]*srcData[11]) * det;
651
652    _data[15] = (srcData[4]*srcData[9]*srcData[2] -
653                 srcData[8]*srcData[5]*srcData[2] +
654                 srcData[8]*srcData[1]*srcData[6] -
655                 srcData[0]*srcData[9]*srcData[6] -
656                 srcData[4]*srcData[1]*srcData[10] +
657                 srcData[0]*srcData[5]*srcData[10]) * det;
658}
659
660Matrix4x4d
661Matrix4x4d::inverse() const
662{
663    const double *m = _data;
664    Matrix4x4d p;
665
666    double m00 = m[0], m01 = m[4], m02 = m[8], m03 = m[12];
667    double m10 = m[1], m11 = m[5], m12 = m[9], m13 = m[13];
668    double m20 = m[2], m21 = m[6], m22 = m[10], m23 = m[14];
669    double m30 = m[3], m31 = m[7], m32 = m[11], m33 = m[15];
670
671    double det0, inv0;
672
673#define det33(a1,a2,a3,b1,b2,b3,c1,c2,c3) \
674    (a1*(b2*c3-b3*c2) + b1*(c2*a3-a2*c3) + c1*(a2*b3-a3*b2))
675
676    double cof00 =  det33(m11, m12, m13, m21, m22, m23, m31, m32, m33);
677    double cof01 = -det33(m12, m13, m10, m22, m23, m20, m32, m33, m30);
678    double cof02 =  det33(m13, m10, m11, m23, m20, m21, m33, m30, m31);
679    double cof03 = -det33(m10, m11, m12, m20, m21, m22, m30, m31, m32);
680
681    double cof10 = -det33(m21, m22, m23, m31, m32, m33, m01, m02, m03);
682    double cof11 =  det33(m22, m23, m20, m32, m33, m30, m02, m03, m00);
683    double cof12 = -det33(m23, m20, m21, m33, m30, m31, m03, m00, m01);
684    double cof13 =  det33(m20, m21, m22, m30, m31, m32, m00, m01, m02);
685
686    double cof20 =  det33(m31, m32, m33, m01, m02, m03, m11, m12, m13);
687    double cof21 = -det33(m32, m33, m30, m02, m03, m00, m12, m13, m10);
688    double cof22 =  det33(m33, m30, m31, m03, m00, m01, m13, m10, m11);
689    double cof23 = -det33(m30, m31, m32, m00, m01, m02, m10, m11, m12);
690
691    double cof30 = -det33(m01, m02, m03, m11, m12, m13, m21, m22, m23);
692    double cof31 =  det33(m02, m03, m00, m12, m13, m10, m22, m23, m20);
693    double cof32 = -det33(m03, m00, m01, m13, m10, m11, m23, m20, m21);
694    double cof33 =  det33(m00, m01, m02, m10, m11, m12, m20, m21, m22);
695
696#undef det33
697
698#if 0
699    TRACE("Invert:");
700    TRACE("   %12.9f %12.9f %12.9f %12.9f", m00, m01, m02, m03);
701    TRACE("   %12.9f %12.9f %12.9f %12.9f", m10, m11, m12, m13);
702    TRACE("   %12.9f %12.9f %12.9f %12.9f", m20, m21, m22, m23);
703    TRACE("   %12.9f %12.9f %12.9f %12.9f", m30, m31, m32, m33);
704#endif
705
706#if 0
707    det0  = m00 * cof00 + m01 * cof01 + m02 * cof02 + m03 * cof03;
708#else
709    det0  = m30 * cof30 + m31 * cof31 + m32 * cof32 + m33 * cof33;
710#endif
711    inv0  = (det0 == 0.0f) ? 0.0f : 1.0f / det0;
712
713    p.get()[0] = cof00 * inv0;
714    p.get()[1] = cof01 * inv0;
715    p.get()[2] = cof02 * inv0;
716    p.get()[3] = cof03 * inv0;
717
718    p.get()[4] = cof10 * inv0;
719    p.get()[5] = cof11 * inv0;
720    p.get()[6] = cof12 * inv0;
721    p.get()[7] = cof13 * inv0;
722
723    p.get()[8] = cof20 * inv0;
724    p.get()[9] = cof21 * inv0;
725    p.get()[10] = cof22 * inv0;
726    p.get()[11] = cof23 * inv0;
727
728    p.get()[12] = cof30 * inv0;
729    p.get()[13] = cof31 * inv0;
730    p.get()[14] = cof32 * inv0;
731    p.get()[15] = cof33 * inv0;
732
733    return p;
734}
735
736void Matrix4x4d::transpose()
737{
738    double m[16];
739
740    m[0] = _data[0];
741    m[1] = _data[4];
742    m[2] = _data[8];
743    m[3] = _data[12];
744
745    m[4] = _data[1];
746    m[5] = _data[5];
747    m[6] = _data[9];
748    m[7] = _data[13];
749
750    m[8] = _data[2];
751    m[9] = _data[6];
752    m[10] = _data[10];
753    m[11] = _data[14];
754
755    m[12] = _data[3];
756    m[13] = _data[7];
757    m[14] = _data[11];
758    m[15] = _data[15];
759
760    set(m);
761}
762
763void Matrix4x4d::transposeFast(const Matrix4x4d& mat)
764{
765    _data[0] = mat._data[0];
766    _data[1] = mat._data[4];
767    _data[2] = mat._data[8];
768    _data[3] = mat._data[12];
769
770    _data[4] = mat._data[1];
771    _data[5] = mat._data[5];
772    _data[6] = mat._data[9];
773    _data[7] = mat._data[13];
774
775    _data[8] = mat._data[2];
776    _data[9] = mat._data[6];
777    _data[10] = mat._data[10];
778    _data[11] = mat._data[14];
779
780    _data[12] = mat._data[3];
781    _data[13] = mat._data[7];
782    _data[14] = mat._data[11];
783    _data[15] = mat._data[15];
784}
785
786void Matrix4x4d::transpose(const Matrix4x4d& mat)
787{
788    if (&mat == this) {
789        transpose();
790    } else {
791        transposeFast(mat);
792    }
793}
794
795void Matrix4x4d::setFloat(const float *m)
796{
797    for (int i = 0; i < 16; ++i) {
798        _data[i] = m[i];
799    }
800}
801
802void Matrix4x4d::multiply(const Matrix4x4d& mat1, const Vector3f& position)
803{
804    Matrix4x4d mat;
805    mat.makeTranslation(position);
806    multiply(mat1, mat);
807}
808
809void Matrix4x4d::multiply(const Matrix4x4d& mat1, const Rotation& rotation)
810{
811    Matrix4x4d mat;
812    mat.makeRotation(rotation);
813    multiply(mat1, mat);
814}
815
816void Matrix4x4d::multiply(const Vector3f& position, const Matrix4x4d& mat1)
817{
818    Matrix4x4d mat;
819    mat.makeTranslation(position);
820    multiply(mat, mat1);
821}
822
823void Matrix4x4d::multiply(const Rotation& rotation, const Matrix4x4d& mat1)
824{
825    Matrix4x4d mat;
826    mat.makeRotation(rotation);
827    multiply(mat, mat1);
828}
829
830void Matrix4x4d::makeVecRotVec(const Vector3f& vec1, const Vector3f& vec2)
831{
832    Vector3f axis = cross(vec1, vec2);
833
834    float angle = atan2(axis.length(), vec1.dot(vec2));
835    axis = axis.normalize();
836    makeRotation(axis.x, axis.y, axis.z, angle);
837}
838
839void Matrix4x4d::multiplyScale(const Matrix4x4d& mat1, const Vector3f& scale)
840{
841    Matrix4x4d mat;
842    mat.makeScale(scale);
843    multiply(mat1, mat);
844}
845
846void Matrix4x4d::multiplyScale(const Vector3f& scale, const Matrix4x4d& mat1)
847{
848    Matrix4x4d mat;
849    mat.makeScale(scale);
850    multiply(mat, mat1);
851}
Note: See TracBrowser for help on using the repository browser.