source: trunk/packages/vizservers/nanovis/vrmath/Matrix4x4d.cpp @ 3492

Last change on this file since 3492 was 3492, checked in by ldelgass, 11 years ago

Fix camera reset for nanovis. Includes refactoring of vector/matrix classes
in nanovis to consolidate into vrmath library. Also add preliminary canonical
view control to clients for testing.

  • Property svn:eol-style set to native
File size: 35.3 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    double mat[16];
232    const double *mat1 = m1._data;
233    const double *mat2 = m2._data;
234
235    // 1 row
236    mat[0] = mat1[0] * mat2[0] + mat1[4] * mat2[1] +
237             mat1[8] * mat2[2] + mat1[12] * mat2[3];
238    mat[4] = mat1[0] * mat2[4] + mat1[4] * mat2[5] +
239             mat1[8] * mat2[6] + mat1[12] * mat2[7];
240    mat[8] = mat1[0] * mat2[8] + mat1[4] * mat2[9] +
241             mat1[8] * mat2[10] + mat1[12] * mat2[11];
242    mat[12] = mat1[0] * mat2[12] + mat1[4] * mat2[13] +
243              mat1[8] * mat2[14] + mat1[12] * mat2[15];
244
245    // 2 row
246    mat[1] = mat1[1] * mat2[0] + mat1[5] * mat2[1] +
247             mat1[9] * mat2[2] + mat1[13] * mat2[3];
248    mat[5] = mat1[1] * mat2[4] + mat1[5] * mat2[5] +
249             mat1[9] * mat2[6] + mat1[13] * mat2[7];
250    mat[9] = mat1[1] * mat2[8] + mat1[5] * mat2[9] +
251             mat1[9] * mat2[10] + mat1[13] * mat2[11];
252    mat[13] = mat1[1] * mat2[12] + mat1[5] * mat2[13] +
253              mat1[9] * mat2[14] + mat1[13] * mat2[15];
254
255    // 3 row
256    mat[2] = mat1[2] * mat2[0] + mat1[6] * mat2[1] +
257             mat1[10] * mat2[2] + mat1[14] * mat2[3];
258    mat[6] = mat1[2] * mat2[4] + mat1[6] * mat2[5] +
259             mat1[10] * mat2[6] + mat1[14] * mat2[7];
260    mat[10] = mat1[2] * mat2[8] + mat1[6] * mat2[9] +
261              mat1[10] * mat2[10] + mat1[14] * mat2[11];
262    mat[14] = mat1[2] * mat2[12] + mat1[6] * mat2[13] +
263              mat1[10] * mat2[14] + mat1[14] * mat2[15];
264
265    // 4 row
266    mat[3] = mat1[3] * mat2[0] + mat1[7] * mat2[1] +
267             mat1[11] * mat2[2] + mat1[15] * mat2[3];
268    mat[7] = mat1[3] * mat2[4] + mat1[7] * mat2[5] +
269             mat1[11] * mat2[6] + mat1[15] * mat2[7];
270    mat[11] = mat1[3] * mat2[8] + mat1[7] * mat2[9] +
271              mat1[11] * mat2[10] + mat1[15] * mat2[11];
272    mat[15] = mat1[3] * mat2[12] + mat1[7] * mat2[13] +
273              mat1[11] * mat2[14] + mat1[15] * mat2[15];
274
275    // set matrix
276    set(mat);
277}
278
279void Matrix4x4d::multiplyFast(const Matrix4x4d& m1, const Matrix4x4d& m2)
280{
281    const double *mat1 = m1._data;
282    const double *mat2 = m2._data;
283
284    // 1 row
285    _data[0] = mat1[0] * mat2[0] + mat1[4] * mat2[1] +
286               mat1[8] * mat2[2] + mat1[12] * mat2[3];
287    _data[4] = mat1[0] * mat2[4] + mat1[4] * mat2[5] +
288               mat1[8] * mat2[6] + mat1[12] * mat2[7];
289    _data[8] = mat1[0] * mat2[8] + mat1[4] * mat2[9] +
290               mat1[8] * mat2[10] + mat1[12] * mat2[11];
291    _data[12] = mat1[0] * mat2[12] + mat1[4] * mat2[13] +
292                mat1[8] * mat2[14] + mat1[12] * mat2[15];
293
294    // 2 row
295    _data[1] = mat1[1] * mat2[0] + mat1[5] * mat2[1] +
296               mat1[9] * mat2[2] + mat1[13] * mat2[3];
297    _data[5] = mat1[1] * mat2[4] + mat1[5] * mat2[5] +
298               mat1[9] * mat2[6] + mat1[13] * mat2[7];
299    _data[9] = mat1[1] * mat2[8] + mat1[5] * mat2[9] +
300               mat1[9] * mat2[10] + mat1[13] * mat2[11];
301    _data[13] = mat1[1] * mat2[12] + mat1[5] * mat2[13] +
302                mat1[9] * mat2[14] + mat1[13] * mat2[15];
303
304    // 3 row
305    _data[2] = mat1[2] * mat2[0] + mat1[6] * mat2[1] +
306               mat1[10] * mat2[2] + mat1[14] * mat2[3];
307    _data[6] = mat1[2] * mat2[4] + mat1[6] * mat2[5] +
308               mat1[10] * mat2[6] + mat1[14] * mat2[7];
309    _data[10] = mat1[2] * mat2[8] + mat1[6] * mat2[9] +
310                mat1[10] * mat2[10] + mat1[14] * mat2[11];
311    _data[14] = mat1[2] * mat2[12] + mat1[6] * mat2[13] +
312                mat1[10] * mat2[14] + mat1[14] * mat2[15];
313
314    // 4 row
315    _data[3] = mat1[3] * mat2[0] + mat1[7] * mat2[1] +
316               mat1[11] * mat2[2] + mat1[15] * mat2[3];
317    _data[7] = mat1[3] * mat2[4] + mat1[7] * mat2[5] +
318               mat1[11] * mat2[6] + mat1[15] * mat2[7];
319    _data[11] = mat1[3] * mat2[8] + mat1[7] * mat2[9] +
320                mat1[11] * mat2[10] + mat1[15] * mat2[11];
321    _data[15] = mat1[3] * mat2[12] + mat1[7] * mat2[13] +
322                mat1[11] * mat2[14] + mat1[15] * mat2[15];
323}
324
325void Matrix4x4d::getRotation(Rotation& rotation)
326{
327    double c = (_data[0] + _data[5] + _data[10] - 1.0) * 0.5;
328
329    rotation.setAxis(_data[6] - _data[9], _data[8] - _data[2], _data[1] - _data[4]);
330
331    double len = sqrt(rotation.getX() * rotation.getX() +
332                      rotation.getY() * rotation.getY() +
333                      rotation.getZ() * rotation.getZ());
334
335    double s = 0.5 * len;
336
337    rotation.setAngle(atan2(s, c));
338
339    if (rotation.getX() == 0.0 &&
340        rotation.getY() == 0.0 &&
341        rotation.getZ() == 0.0) {
342        rotation.set(0, 1, 0, 0);
343    } else {
344        len = 1.0 / len;
345        rotation.setAxis(rotation.getX() * len,
346                         rotation.getY() * len,
347                         rotation.getZ() * len);
348    }
349}
350
351void Matrix4x4d::invert()
352{
353    double det =
354        _data[12] * _data[9] * _data[6] * _data[3]-
355        _data[8] * _data[13] * _data[6] * _data[3]-
356        _data[12] * _data[5] * _data[10] * _data[3]+
357        _data[4] * _data[13] * _data[10] * _data[3]+
358        _data[8] * _data[5] * _data[14] * _data[3]-
359        _data[4] * _data[9] * _data[14] * _data[3]-
360        _data[12] * _data[9] * _data[2] * _data[7]+
361        _data[8] * _data[13] * _data[2] * _data[7]+
362        _data[12] * _data[1] * _data[10] * _data[7]-
363        _data[0] * _data[13] * _data[10] * _data[7]-
364        _data[8] * _data[1] * _data[14] * _data[7]+
365        _data[0] * _data[9] * _data[14] * _data[7]+
366        _data[12] * _data[5] * _data[2] * _data[11]-
367        _data[4] * _data[13] * _data[2] * _data[11]-
368        _data[12] * _data[1] * _data[6] * _data[11]+
369        _data[0] * _data[13] * _data[6] * _data[11]+
370        _data[4] * _data[1] * _data[14] * _data[11]-
371        _data[0] * _data[5] * _data[14] * _data[11]-
372        _data[8] * _data[5] * _data[2] * _data[15]+
373        _data[4] * _data[9] * _data[2] * _data[15]+
374        _data[8] * _data[1] * _data[6] * _data[15]-
375        _data[0] * _data[9] * _data[6] * _data[15]-
376        _data[4] * _data[1] * _data[10] * _data[15]+
377        _data[0] * _data[5] * _data[10] * _data[15];
378
379    if ( det == 0.0 ) return;
380    det = 1.0 / det;
381
382    double mat[16];
383
384    mat[0] = (_data[9]*_data[14]*_data[7] -
385              _data[13]*_data[10]*_data[7] +
386              _data[13]*_data[6]*_data[11] -
387              _data[5]*_data[14]*_data[11] -
388              _data[9]*_data[6]*_data[15] +
389              _data[5]*_data[10]*_data[15]) * det;
390
391    mat[4] = (_data[12]*_data[10]*_data[7] -
392              _data[8]*_data[14]*_data[7] -
393              _data[12]*_data[6]*_data[11] +
394              _data[4]*_data[14]*_data[11] +
395              _data[8]*_data[6]*_data[15] -
396              _data[4]*_data[10]*_data[15]) * det;
397
398    mat[8] = (_data[8]*_data[13]*_data[7] -
399              _data[12]*_data[9]*_data[7] +
400              _data[12]*_data[5]*_data[11] -
401              _data[4]*_data[13]*_data[11] -
402              _data[8]*_data[5]*_data[15] +
403              _data[4]*_data[9]*_data[15]) * det;
404
405    mat[12] = (_data[12]*_data[9]*_data[6] -
406               _data[8]*_data[13]*_data[6] -
407               _data[12]*_data[5]*_data[10] +
408               _data[4]*_data[13]*_data[10] +
409               _data[8]*_data[5]*_data[14] -
410               _data[4]*_data[9]*_data[14]) * det;
411
412    mat[1] = (_data[13]*_data[10]*_data[3] -
413              _data[9]*_data[14]*_data[3] -
414              _data[13]*_data[2]*_data[11] +
415              _data[1]*_data[14]*_data[11] +
416              _data[9]*_data[2]*_data[15] -
417              _data[1]*_data[10]*_data[15]) * det;
418
419    mat[5] = (_data[8]*_data[14]*_data[3] -
420              _data[12]*_data[10]*_data[3] +
421              _data[12]*_data[2]*_data[11] -
422              _data[0]*_data[14]*_data[11] -
423              _data[8]*_data[2]*_data[15] +
424              _data[0]*_data[10]*_data[15]) * det;
425
426    mat[9] = (_data[12]*_data[9]*_data[3] -
427              _data[8]*_data[13]*_data[3] -
428              _data[12]*_data[1]*_data[11] +
429              _data[0]*_data[13]*_data[11] +
430              _data[8]*_data[1]*_data[15] -
431              _data[0]*_data[9]*_data[15]) * det;
432
433    mat[13] = (_data[8]*_data[13]*_data[2] -
434               _data[12]*_data[9]*_data[2] +
435               _data[12]*_data[1]*_data[10] -
436               _data[0]*_data[13]*_data[10] -
437               _data[8]*_data[1]*_data[14] +
438               _data[0]*_data[9]*_data[14]) * det;
439
440    mat[2] = (_data[5]*_data[14]*_data[3] -
441              _data[13]*_data[6]*_data[3] +
442              _data[13]*_data[2]*_data[7] -
443              _data[1]*_data[14]*_data[7] -
444              _data[5]*_data[2]*_data[15] +
445              _data[1]*_data[6]*_data[15]) * det;
446
447    mat[6] = (_data[12]*_data[6]*_data[3] -
448              _data[4]*_data[14]*_data[3] -
449              _data[12]*_data[2]*_data[7] +
450              _data[0]*_data[14]*_data[7] +
451              _data[4]*_data[2]*_data[15] -
452              _data[0]*_data[6]*_data[15]) * det;
453
454    mat[10] = (_data[4]*_data[13]*_data[3] -
455               _data[12]*_data[5]*_data[3] +
456               _data[12]*_data[1]*_data[7] -
457               _data[0]*_data[13]*_data[7] -
458               _data[4]*_data[1]*_data[15] +
459               _data[0]*_data[5]*_data[15]) * det;
460
461    mat[14] = (_data[12]*_data[5]*_data[2] -
462               _data[4]*_data[13]*_data[2] -
463               _data[12]*_data[1]*_data[6] +
464               _data[0]*_data[13]*_data[6] +
465               _data[4]*_data[1]*_data[14] -
466               _data[0]*_data[5]*_data[14]) * det;
467
468    mat[3] = (_data[9]*_data[6]*_data[3] -
469              _data[5]*_data[10]*_data[3] -
470              _data[9]*_data[2]*_data[7] +
471              _data[1]*_data[10]*_data[7] +
472              _data[5]*_data[2]*_data[11] -
473              _data[1]*_data[6]*_data[11]) * det;
474
475    mat[7] = (_data[4]*_data[10]*_data[3] -
476              _data[8]*_data[6]*_data[3] +
477              _data[8]*_data[2]*_data[7] -
478              _data[0]*_data[10]*_data[7] -
479              _data[4]*_data[2]*_data[11] +
480              _data[0]*_data[6]*_data[11]) * det;
481
482    mat[11] = (_data[8]*_data[5]*_data[3] -
483               _data[4]*_data[9]*_data[3] -
484               _data[8]*_data[1]*_data[7] +
485               _data[0]*_data[9]*_data[7] +
486               _data[4]*_data[1]*_data[11] -
487               _data[0]*_data[5]*_data[11]) * det;
488
489    mat[15] = (_data[4]*_data[9]*_data[2] -
490               _data[8]*_data[5]*_data[2] +
491               _data[8]*_data[1]*_data[6] -
492               _data[0]*_data[9]*_data[6] -
493               _data[4]*_data[1]*_data[10] +
494               _data[0]*_data[5]*_data[10]) * det;
495
496    set(mat);
497}
498
499void Matrix4x4d::invert(const Matrix4x4d& mat)
500{
501    const double *data = mat._data;
502
503    double det =
504        data[12] * data[9] * data[6] * data[3]-
505        data[8] * data[13] * data[6] * data[3]-
506        data[12] * data[5] * data[10] * data[3]+
507        data[4] * data[13] * data[10] * data[3]+
508        data[8] * data[5] * data[14] * data[3]-
509        data[4] * data[9] * data[14] * data[3]-
510        data[12] * data[9] * data[2] * data[7]+
511        data[8] * data[13] * data[2] * data[7]+
512        data[12] * data[1] * data[10] * data[7]-
513        data[0] * data[13] * data[10] * data[7]-
514        data[8] * data[1] * data[14] * data[7]+
515        data[0] * data[9] * data[14] * data[7]+
516        data[12] * data[5] * data[2] * data[11]-
517        data[4] * data[13] * data[2] * data[11]-
518        data[12] * data[1] * data[6] * data[11]+
519        data[0] * data[13] * data[6] * data[11]+
520        data[4] * data[1] * data[14] * data[11]-
521        data[0] * data[5] * data[14] * data[11]-
522        data[8] * data[5] * data[2] * data[15]+
523        data[4] * data[9] * data[2] * data[15]+
524        data[8] * data[1] * data[6] * data[15]-
525        data[0] * data[9] * data[6] * data[15]-
526        data[4] * data[1] * data[10] * data[15]+
527        data[0] * data[5] * data[10] * data[15];
528
529    if ( det == 0.0 ) return;
530    det = 1.0 / det;
531
532    double dstData[16];
533
534    dstData[0] = (data[9]*data[14]*data[7] -
535                  data[13]*data[10]*data[7] +
536                  data[13]*data[6]*data[11] -
537                  data[5]*data[14]*data[11] -
538                  data[9]*data[6]*data[15] +
539                  data[5]*data[10]*data[15]) * det;
540
541    dstData[4] = (data[12]*data[10]*data[7] -
542                  data[8]*data[14]*data[7] -
543                  data[12]*data[6]*data[11] +
544                  data[4]*data[14]*data[11] +
545                  data[8]*data[6]*data[15] -
546                  data[4]*data[10]*data[15]) * det;
547
548    dstData[8] = (data[8]*data[13]*data[7] -
549                  data[12]*data[9]*data[7] +
550                  data[12]*data[5]*data[11] -
551                  data[4]*data[13]*data[11] -
552                  data[8]*data[5]*data[15] +
553                  data[4]*data[9]*data[15]) * det;
554
555    dstData[12] = (data[12]*data[9]*data[6] -
556                   data[8]*data[13]*data[6] -
557                   data[12]*data[5]*data[10] +
558                   data[4]*data[13]*data[10] +
559                   data[8]*data[5]*data[14] -
560                   data[4]*data[9]*data[14]) * det;
561
562    dstData[1] = (data[13]*data[10]*data[3] -
563                  data[9]*data[14]*data[3] -
564                  data[13]*data[2]*data[11] +
565                  data[1]*data[14]*data[11] +
566                  data[9]*data[2]*data[15] -
567                  data[1]*data[10]*data[15]) * det;
568
569    dstData[5] = (data[8]*data[14]*data[3] -
570                  data[12]*data[10]*data[3] +
571                  data[12]*data[2]*data[11] -
572                  data[0]*data[14]*data[11] -
573                  data[8]*data[2]*data[15] +
574                  data[0]*data[10]*data[15]) * det;
575
576    dstData[9] = (data[12]*data[9]*data[3] -
577                  data[8]*data[13]*data[3] -
578                  data[12]*data[1]*data[11] +
579                  data[0]*data[13]*data[11] +
580                  data[8]*data[1]*data[15] -
581                  data[0]*data[9]*data[15]) * det;
582
583    dstData[13] = (data[8]*data[13]*data[2] -
584                   data[12]*data[9]*data[2] +
585                   data[12]*data[1]*data[10] -
586                   data[0]*data[13]*data[10] -
587                   data[8]*data[1]*data[14] +
588                   data[0]*data[9]*data[14]) * det;
589
590    dstData[2] = (data[5]*data[14]*data[3] -
591                  data[13]*data[6]*data[3] +
592                  data[13]*data[2]*data[7] -
593                  data[1]*data[14]*data[7] -
594                  data[5]*data[2]*data[15] +
595                  data[1]*data[6]*data[15]) * det;
596
597    dstData[6] = (data[12]*data[6]*data[3] -
598                  data[4]*data[14]*data[3] -
599                  data[12]*data[2]*data[7] +
600                  data[0]*data[14]*data[7] +
601                  data[4]*data[2]*data[15] -
602                  data[0]*data[6]*data[15]) * det;
603
604    dstData[10] = (data[4]*data[13]*data[3] -
605                   data[12]*data[5]*data[3] +
606                   data[12]*data[1]*data[7] -
607                   data[0]*data[13]*data[7] -
608                   data[4]*data[1]*data[15] +
609                   data[0]*data[5]*data[15]) * det;
610
611    dstData[14] = (data[12]*data[5]*data[2] -
612                   data[4]*data[13]*data[2] -
613                   data[12]*data[1]*data[6] +
614                   data[0]*data[13]*data[6] +
615                   data[4]*data[1]*data[14] -
616                   data[0]*data[5]*data[14]) * det;
617
618    dstData[3] = (data[9]*data[6]*data[3] -
619                  data[5]*data[10]*data[3] -
620                  data[9]*data[2]*data[7] +
621                  data[1]*data[10]*data[7] +
622                  data[5]*data[2]*data[11] -
623                  data[1]*data[6]*data[11]) * det;
624
625    dstData[7] = (data[4]*data[10]*data[3] -
626                  data[8]*data[6]*data[3] +
627                  data[8]*data[2]*data[7] -
628                  data[0]*data[10]*data[7] -
629                  data[4]*data[2]*data[11] +
630                  data[0]*data[6]*data[11]) * det;
631
632    dstData[11] = (data[8]*data[5]*data[3] -
633                   data[4]*data[9]*data[3] -
634                   data[8]*data[1]*data[7] +
635                   data[0]*data[9]*data[7] +
636                   data[4]*data[1]*data[11] -
637                   data[0]*data[5]*data[11]) * det;
638
639    dstData[15] = (data[4]*data[9]*data[2] -
640                   data[8]*data[5]*data[2] +
641                   data[8]*data[1]*data[6] -
642                   data[0]*data[9]*data[6] -
643                   data[4]*data[1]*data[10] +
644                   data[0]*data[5]*data[10]) * det;
645
646    set(dstData);
647}
648
649void Matrix4x4d::invertFast(const Matrix4x4d& mat)
650{
651    const double *srcData = mat._data;
652
653    double det =
654        srcData[12] * srcData[9] * srcData[6] * srcData[3]-
655        srcData[8] * srcData[13] * srcData[6] * srcData[3]-
656        srcData[12] * srcData[5] * srcData[10] * srcData[3]+
657        srcData[4] * srcData[13] * srcData[10] * srcData[3]+
658        srcData[8] * srcData[5] * srcData[14] * srcData[3]-
659        srcData[4] * srcData[9] * srcData[14] * srcData[3]-
660        srcData[12] * srcData[9] * srcData[2] * srcData[7]+
661        srcData[8] * srcData[13] * srcData[2] * srcData[7]+
662        srcData[12] * srcData[1] * srcData[10] * srcData[7]-
663        srcData[0] * srcData[13] * srcData[10] * srcData[7]-
664        srcData[8] * srcData[1] * srcData[14] * srcData[7]+
665        srcData[0] * srcData[9] * srcData[14] * srcData[7]+
666        srcData[12] * srcData[5] * srcData[2] * srcData[11]-
667        srcData[4] * srcData[13] * srcData[2] * srcData[11]-
668        srcData[12] * srcData[1] * srcData[6] * srcData[11]+
669        srcData[0] * srcData[13] * srcData[6] * srcData[11]+
670        srcData[4] * srcData[1] * srcData[14] * srcData[11]-
671        srcData[0] * srcData[5] * srcData[14] * srcData[11]-
672        srcData[8] * srcData[5] * srcData[2] * srcData[15]+
673        srcData[4] * srcData[9] * srcData[2] * srcData[15]+
674        srcData[8] * srcData[1] * srcData[6] * srcData[15]-
675        srcData[0] * srcData[9] * srcData[6] * srcData[15]-
676        srcData[4] * srcData[1] * srcData[10] * srcData[15]+
677        srcData[0] * srcData[5] * srcData[10] * srcData[15];
678
679    if ( det == 0.0 ) return;
680    det = 1.0 / det;
681
682    _data[0] = (srcData[9]*srcData[14]*srcData[7] -
683                srcData[13]*srcData[10]*srcData[7] +
684                srcData[13]*srcData[6]*srcData[11] -
685                srcData[5]*srcData[14]*srcData[11] -
686                srcData[9]*srcData[6]*srcData[15] +
687                srcData[5]*srcData[10]*srcData[15]) * det;
688
689    _data[4] = (srcData[12]*srcData[10]*srcData[7] -
690                srcData[8]*srcData[14]*srcData[7] -
691                srcData[12]*srcData[6]*srcData[11] +
692                srcData[4]*srcData[14]*srcData[11] +
693                srcData[8]*srcData[6]*srcData[15] -
694                srcData[4]*srcData[10]*srcData[15]) * det;
695
696    _data[8] = (srcData[8]*srcData[13]*srcData[7] -
697                srcData[12]*srcData[9]*srcData[7] +
698                srcData[12]*srcData[5]*srcData[11] -
699                srcData[4]*srcData[13]*srcData[11] -
700                srcData[8]*srcData[5]*srcData[15] +
701                srcData[4]*srcData[9]*srcData[15]) * det;
702
703    _data[12] = (srcData[12]*srcData[9]*srcData[6] -
704                 srcData[8]*srcData[13]*srcData[6] -
705                 srcData[12]*srcData[5]*srcData[10] +
706                 srcData[4]*srcData[13]*srcData[10] +
707                 srcData[8]*srcData[5]*srcData[14] -
708                 srcData[4]*srcData[9]*srcData[14]) * det;
709
710    _data[1] = (srcData[13]*srcData[10]*srcData[3] -
711                srcData[9]*srcData[14]*srcData[3] -
712                srcData[13]*srcData[2]*srcData[11] +
713                srcData[1]*srcData[14]*srcData[11] +
714                srcData[9]*srcData[2]*srcData[15] -
715                srcData[1]*srcData[10]*srcData[15]) * det;
716
717    _data[5] = (srcData[8]*srcData[14]*srcData[3] -
718                srcData[12]*srcData[10]*srcData[3] +
719                srcData[12]*srcData[2]*srcData[11] -
720                srcData[0]*srcData[14]*srcData[11] -
721                srcData[8]*srcData[2]*srcData[15] +
722                srcData[0]*srcData[10]*srcData[15]) * det;
723
724    _data[9] = (srcData[12]*srcData[9]*srcData[3] -
725                srcData[8]*srcData[13]*srcData[3] -
726                srcData[12]*srcData[1]*srcData[11] +
727                srcData[0]*srcData[13]*srcData[11] +
728                srcData[8]*srcData[1]*srcData[15] -
729                srcData[0]*srcData[9]*srcData[15]) * det;
730
731    _data[13] = (srcData[8]*srcData[13]*srcData[2] -
732                 srcData[12]*srcData[9]*srcData[2] +
733                 srcData[12]*srcData[1]*srcData[10] -
734                 srcData[0]*srcData[13]*srcData[10] -
735                 srcData[8]*srcData[1]*srcData[14] +
736                 srcData[0]*srcData[9]*srcData[14]) * det;
737
738    _data[2] = (srcData[5]*srcData[14]*srcData[3] -
739                srcData[13]*srcData[6]*srcData[3] +
740                srcData[13]*srcData[2]*srcData[7] -
741                srcData[1]*srcData[14]*srcData[7] -
742                srcData[5]*srcData[2]*srcData[15] +
743                srcData[1]*srcData[6]*srcData[15]) * det;
744
745    _data[6] = (srcData[12]*srcData[6]*srcData[3] -
746                srcData[4]*srcData[14]*srcData[3] -
747                srcData[12]*srcData[2]*srcData[7] +
748                srcData[0]*srcData[14]*srcData[7] +
749                srcData[4]*srcData[2]*srcData[15] -
750                srcData[0]*srcData[6]*srcData[15]) * det;
751
752    _data[10] = (srcData[4]*srcData[13]*srcData[3] -
753                 srcData[12]*srcData[5]*srcData[3] +
754                 srcData[12]*srcData[1]*srcData[7] -
755                 srcData[0]*srcData[13]*srcData[7] -
756                 srcData[4]*srcData[1]*srcData[15] +
757                 srcData[0]*srcData[5]*srcData[15]) * det;
758
759    _data[14] = (srcData[12]*srcData[5]*srcData[2] -
760                 srcData[4]*srcData[13]*srcData[2] -
761                 srcData[12]*srcData[1]*srcData[6] +
762                 srcData[0]*srcData[13]*srcData[6] +
763                 srcData[4]*srcData[1]*srcData[14] -
764                 srcData[0]*srcData[5]*srcData[14]) * det;
765
766    _data[3] = (srcData[9]*srcData[6]*srcData[3] -
767                srcData[5]*srcData[10]*srcData[3] -
768                srcData[9]*srcData[2]*srcData[7] +
769                srcData[1]*srcData[10]*srcData[7] +
770                srcData[5]*srcData[2]*srcData[11] -
771                srcData[1]*srcData[6]*srcData[11]) * det;
772
773    _data[7] = (srcData[4]*srcData[10]*srcData[3] -
774                srcData[8]*srcData[6]*srcData[3] +
775                srcData[8]*srcData[2]*srcData[7] -
776                srcData[0]*srcData[10]*srcData[7] -
777                srcData[4]*srcData[2]*srcData[11] +
778                srcData[0]*srcData[6]*srcData[11]) * det;
779
780    _data[11] = (srcData[8]*srcData[5]*srcData[3] -
781                 srcData[4]*srcData[9]*srcData[3] -
782                 srcData[8]*srcData[1]*srcData[7] +
783                 srcData[0]*srcData[9]*srcData[7] +
784                 srcData[4]*srcData[1]*srcData[11] -
785                 srcData[0]*srcData[5]*srcData[11]) * det;
786
787    _data[15] = (srcData[4]*srcData[9]*srcData[2] -
788                 srcData[8]*srcData[5]*srcData[2] +
789                 srcData[8]*srcData[1]*srcData[6] -
790                 srcData[0]*srcData[9]*srcData[6] -
791                 srcData[4]*srcData[1]*srcData[10] +
792                 srcData[0]*srcData[5]*srcData[10]) * det;
793}
794
795Matrix4x4d
796Matrix4x4d::inverse() const
797{
798    const double *m = _data;
799    Matrix4x4d p;
800
801    double m00 = m[0], m01 = m[4], m02 = m[8], m03 = m[12];
802    double m10 = m[1], m11 = m[5], m12 = m[9], m13 = m[13];
803    double m20 = m[2], m21 = m[6], m22 = m[10], m23 = m[14];
804    double m30 = m[3], m31 = m[7], m32 = m[11], m33 = m[15];
805
806    double det0, inv0;
807
808#define det33(a1,a2,a3,b1,b2,b3,c1,c2,c3) \
809    (a1*(b2*c3-b3*c2) + b1*(c2*a3-a2*c3) + c1*(a2*b3-a3*b2))
810
811    double cof00 =  det33(m11, m12, m13, m21, m22, m23, m31, m32, m33);
812    double cof01 = -det33(m12, m13, m10, m22, m23, m20, m32, m33, m30);
813    double cof02 =  det33(m13, m10, m11, m23, m20, m21, m33, m30, m31);
814    double cof03 = -det33(m10, m11, m12, m20, m21, m22, m30, m31, m32);
815
816    double cof10 = -det33(m21, m22, m23, m31, m32, m33, m01, m02, m03);
817    double cof11 =  det33(m22, m23, m20, m32, m33, m30, m02, m03, m00);
818    double cof12 = -det33(m23, m20, m21, m33, m30, m31, m03, m00, m01);
819    double cof13 =  det33(m20, m21, m22, m30, m31, m32, m00, m01, m02);
820
821    double cof20 =  det33(m31, m32, m33, m01, m02, m03, m11, m12, m13);
822    double cof21 = -det33(m32, m33, m30, m02, m03, m00, m12, m13, m10);
823    double cof22 =  det33(m33, m30, m31, m03, m00, m01, m13, m10, m11);
824    double cof23 = -det33(m30, m31, m32, m00, m01, m02, m10, m11, m12);
825
826    double cof30 = -det33(m01, m02, m03, m11, m12, m13, m21, m22, m23);
827    double cof31 =  det33(m02, m03, m00, m12, m13, m10, m22, m23, m20);
828    double cof32 = -det33(m03, m00, m01, m13, m10, m11, m23, m20, m21);
829    double cof33 =  det33(m00, m01, m02, m10, m11, m12, m20, m21, m22);
830
831#undef det33
832
833#if 0
834    TRACE("Invert:");
835    TRACE("   %12.9f %12.9f %12.9f %12.9f", m00, m01, m02, m03);
836    TRACE("   %12.9f %12.9f %12.9f %12.9f", m10, m11, m12, m13);
837    TRACE("   %12.9f %12.9f %12.9f %12.9f", m20, m21, m22, m23);
838    TRACE("   %12.9f %12.9f %12.9f %12.9f", m30, m31, m32, m33);
839#endif
840
841#if 0
842    det0  = m00 * cof00 + m01 * cof01 + m02 * cof02 + m03 * cof03;
843#else
844    det0  = m30 * cof30 + m31 * cof31 + m32 * cof32 + m33 * cof33;
845#endif
846    inv0  = (det0 == 0.0f) ? 0.0f : 1.0f / det0;
847
848    p.get()[0] = cof00 * inv0;
849    p.get()[1] = cof01 * inv0;
850    p.get()[2] = cof02 * inv0;
851    p.get()[3] = cof03 * inv0;
852
853    p.get()[4] = cof10 * inv0;
854    p.get()[5] = cof11 * inv0;
855    p.get()[6] = cof12 * inv0;
856    p.get()[7] = cof13 * inv0;
857
858    p.get()[8] = cof20 * inv0;
859    p.get()[9] = cof21 * inv0;
860    p.get()[10] = cof22 * inv0;
861    p.get()[11] = cof23 * inv0;
862
863    p.get()[12] = cof30 * inv0;
864    p.get()[13] = cof31 * inv0;
865    p.get()[14] = cof32 * inv0;
866    p.get()[15] = cof33 * inv0;
867
868    return p;
869}
870
871void Matrix4x4d::transpose()
872{
873    double m[16];
874
875    m[0] = _data[0];
876    m[1] = _data[4];
877    m[2] = _data[8];
878    m[3] = _data[12];
879
880    m[4] = _data[1];
881    m[5] = _data[5];
882    m[6] = _data[9];
883    m[7] = _data[13];
884
885    m[8] = _data[2];
886    m[9] = _data[6];
887    m[10] = _data[10];
888    m[11] = _data[14];
889
890    m[12] = _data[3];
891    m[13] = _data[7];
892    m[14] = _data[11];
893    m[15] = _data[15];
894
895    set(m);
896}
897
898void Matrix4x4d::transposeFast(const Matrix4x4d& mat)
899{
900    _data[0] = mat._data[0];
901    _data[1] = mat._data[4];
902    _data[2] = mat._data[8];
903    _data[3] = mat._data[12];
904
905    _data[4] = mat._data[1];
906    _data[5] = mat._data[5];
907    _data[6] = mat._data[9];
908    _data[7] = mat._data[13];
909
910    _data[8] = mat._data[2];
911    _data[9] = mat._data[6];
912    _data[10] = mat._data[10];
913    _data[11] = mat._data[14];
914
915    _data[12] = mat._data[3];
916    _data[13] = mat._data[7];
917    _data[14] = mat._data[11];
918    _data[15] = mat._data[15];
919}
920
921void Matrix4x4d::transpose(const Matrix4x4d& mat)
922{
923    double m[16];
924
925    m[0] = mat._data[0];
926    m[1] = mat._data[4];
927    m[2] = mat._data[8];
928    m[3] = mat._data[12];
929
930    m[4] = mat._data[1];
931    m[5] = mat._data[5];
932    m[6] = mat._data[9];
933    m[7] = mat._data[13];
934
935    m[8] = mat._data[2];
936    m[9] = mat._data[6];
937    m[10] = mat._data[10];
938    m[11] = mat._data[14];
939
940    m[12] = mat._data[3];
941    m[13] = mat._data[7];
942    m[14] = mat._data[11];
943    m[15] = mat._data[15];
944
945    set(m);
946}
947
948void Matrix4x4d::setFloat(float *m)
949{
950    for (int i = 0; i < 16; ++i) {
951        _data[i] = m[i];
952    }
953}
954
955void Matrix4x4d::multiply(const Matrix4x4d& mat1, const Vector3f& position)
956{
957    Matrix4x4d mat;
958    mat.makeTranslation(position);
959    multiply(mat1, mat);
960}
961
962void Matrix4x4d::multiply(const Matrix4x4d& mat1, const Rotation& rotation)
963{
964    Matrix4x4d mat;
965    mat.makeRotation(rotation);
966    multiply(mat1, mat);
967}
968
969void Matrix4x4d::multiply(const Vector3f& position, const Matrix4x4d& mat1)
970{
971    Matrix4x4d mat;
972    mat.makeTranslation(position);
973    multiply(mat, mat1);
974}
975
976void Matrix4x4d::multiply(const Rotation& rotation, const Matrix4x4d& mat1)
977{
978    Matrix4x4d mat;
979    mat.makeRotation(rotation);
980    multiply(mat, mat1);
981}
982
983void Matrix4x4d::makeVecRotVec(const Vector3f& vec1, const Vector3f& vec2)
984{
985    Vector3f axis = cross(vec1, vec2);
986
987    float angle = atan2(axis.length(), vec1.dot(vec2));
988    axis = axis.normalize();
989    makeRotation(axis.x, axis.y, axis.z, angle);
990}
991
992void Matrix4x4d::multiplyScale(const Matrix4x4d& mat1, const Vector3f& scale)
993{
994    Matrix4x4d mat;
995    mat.makeScale(scale);
996    multiply(mat1, mat);
997}
998
999void Matrix4x4d::multiplyScale(const Vector3f& scale, const Matrix4x4d& mat1)
1000{
1001    Matrix4x4d mat;
1002    mat.makeScale(scale);
1003    multiply(mat, mat1);
1004}
Note: See TracBrowser for help on using the repository browser.