aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/m4math.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/m4math.cpp')
-rw-r--r--linden/indra/llmath/m4math.cpp813
1 files changed, 813 insertions, 0 deletions
diff --git a/linden/indra/llmath/m4math.cpp b/linden/indra/llmath/m4math.cpp
new file mode 100644
index 0000000..ee7e6f3
--- /dev/null
+++ b/linden/indra/llmath/m4math.cpp
@@ -0,0 +1,813 @@
1/**
2 * @file m4math.cpp
3 * @brief LLMatrix4 class implementation.
4 *
5 * Copyright (c) 2000-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30//#include "vmath.h"
31#include "v3math.h"
32#include "v4math.h"
33#include "m4math.h"
34#include "m3math.h"
35#include "llquaternion.h"
36
37
38
39
40// LLMatrix4
41
42// Constructors
43
44
45LLMatrix4::LLMatrix4(const F32 *mat)
46{
47 mMatrix[0][0] = mat[0];
48 mMatrix[0][1] = mat[1];
49 mMatrix[0][2] = mat[2];
50 mMatrix[0][3] = mat[3];
51
52 mMatrix[1][0] = mat[4];
53 mMatrix[1][1] = mat[5];
54 mMatrix[1][2] = mat[6];
55 mMatrix[1][3] = mat[7];
56
57 mMatrix[2][0] = mat[8];
58 mMatrix[2][1] = mat[9];
59 mMatrix[2][2] = mat[10];
60 mMatrix[2][3] = mat[11];
61
62 mMatrix[3][0] = mat[12];
63 mMatrix[3][1] = mat[13];
64 mMatrix[3][2] = mat[14];
65 mMatrix[3][3] = mat[15];
66}
67
68LLMatrix4::LLMatrix4(const LLMatrix3 &mat, const LLVector4 &vec)
69{
70 mMatrix[0][0] = mat.mMatrix[0][0];
71 mMatrix[0][1] = mat.mMatrix[0][1];
72 mMatrix[0][2] = mat.mMatrix[0][2];
73 mMatrix[0][3] = 0.f;
74
75 mMatrix[1][0] = mat.mMatrix[1][0];
76 mMatrix[1][1] = mat.mMatrix[1][1];
77 mMatrix[1][2] = mat.mMatrix[1][2];
78 mMatrix[1][3] = 0.f;
79
80 mMatrix[2][0] = mat.mMatrix[2][0];
81 mMatrix[2][1] = mat.mMatrix[2][1];
82 mMatrix[2][2] = mat.mMatrix[2][2];
83 mMatrix[2][3] = 0.f;
84
85 mMatrix[3][0] = vec.mV[0];
86 mMatrix[3][1] = vec.mV[1];
87 mMatrix[3][2] = vec.mV[2];
88 mMatrix[3][3] = 1.f;
89}
90
91LLMatrix4::LLMatrix4(const LLMatrix3 &mat)
92{
93 mMatrix[0][0] = mat.mMatrix[0][0];
94 mMatrix[0][1] = mat.mMatrix[0][1];
95 mMatrix[0][2] = mat.mMatrix[0][2];
96 mMatrix[0][3] = 0.f;
97
98 mMatrix[1][0] = mat.mMatrix[1][0];
99 mMatrix[1][1] = mat.mMatrix[1][1];
100 mMatrix[1][2] = mat.mMatrix[1][2];
101 mMatrix[1][3] = 0.f;
102
103 mMatrix[2][0] = mat.mMatrix[2][0];
104 mMatrix[2][1] = mat.mMatrix[2][1];
105 mMatrix[2][2] = mat.mMatrix[2][2];
106 mMatrix[2][3] = 0.f;
107
108 mMatrix[3][0] = 0.f;
109 mMatrix[3][1] = 0.f;
110 mMatrix[3][2] = 0.f;
111 mMatrix[3][3] = 1.f;
112}
113
114LLMatrix4::LLMatrix4(const LLQuaternion &q)
115{
116 *this = initRotation(q);
117}
118
119LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos)
120{
121 *this = initRotTrans(q, pos);
122}
123
124LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec, const LLVector4 &pos)
125{
126 initRotTrans(LLQuaternion(angle, vec), pos);
127}
128
129LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec)
130{
131 initRotation(LLQuaternion(angle, vec));
132
133 mMatrix[3][0] = 0.f;
134 mMatrix[3][1] = 0.f;
135 mMatrix[3][2] = 0.f;
136 mMatrix[3][3] = 1.f;
137}
138
139LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos)
140{
141 LLMatrix3 mat(roll, pitch, yaw);
142 initRotTrans(LLQuaternion(mat), pos);
143}
144
145LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw)
146{
147 LLMatrix3 mat(roll, pitch, yaw);
148 initRotation(LLQuaternion(mat));
149
150 mMatrix[3][0] = 0.f;
151 mMatrix[3][1] = 0.f;
152 mMatrix[3][2] = 0.f;
153 mMatrix[3][3] = 1.f;
154}
155
156LLMatrix4::~LLMatrix4(void)
157{
158}
159
160// Clear and Assignment Functions
161
162const LLMatrix4& LLMatrix4::zero()
163{
164 mMatrix[0][0] = 0.f;
165 mMatrix[0][1] = 0.f;
166 mMatrix[0][2] = 0.f;
167 mMatrix[0][3] = 0.f;
168
169 mMatrix[1][0] = 0.f;
170 mMatrix[1][1] = 0.f;
171 mMatrix[1][2] = 0.f;
172 mMatrix[1][3] = 0.f;
173
174 mMatrix[2][0] = 0.f;
175 mMatrix[2][1] = 0.f;
176 mMatrix[2][2] = 0.f;
177 mMatrix[2][3] = 0.f;
178
179 mMatrix[3][0] = 0.f;
180 mMatrix[3][1] = 0.f;
181 mMatrix[3][2] = 0.f;
182 mMatrix[3][3] = 0.f;
183 return *this;
184}
185
186
187// various useful mMatrix functions
188
189const LLMatrix4& LLMatrix4::transpose()
190{
191 LLMatrix4 mat;
192 mat.mMatrix[0][0] = mMatrix[0][0];
193 mat.mMatrix[1][0] = mMatrix[0][1];
194 mat.mMatrix[2][0] = mMatrix[0][2];
195 mat.mMatrix[3][0] = mMatrix[0][3];
196
197 mat.mMatrix[0][1] = mMatrix[1][0];
198 mat.mMatrix[1][1] = mMatrix[1][1];
199 mat.mMatrix[2][1] = mMatrix[1][2];
200 mat.mMatrix[3][1] = mMatrix[1][3];
201
202 mat.mMatrix[0][2] = mMatrix[2][0];
203 mat.mMatrix[1][2] = mMatrix[2][1];
204 mat.mMatrix[2][2] = mMatrix[2][2];
205 mat.mMatrix[3][2] = mMatrix[2][3];
206
207 mat.mMatrix[0][3] = mMatrix[3][0];
208 mat.mMatrix[1][3] = mMatrix[3][1];
209 mat.mMatrix[2][3] = mMatrix[3][2];
210 mat.mMatrix[3][3] = mMatrix[3][3];
211
212 *this = mat;
213 return *this;
214}
215
216
217F32 LLMatrix4::determinant() const
218{
219 llerrs << "Not implemented!" << llendl;
220 return 0.f;
221}
222
223// Only works for pure orthonormal, homogeneous transform matrices.
224const LLMatrix4& LLMatrix4::invert(void)
225{
226 // transpose the rotation part
227 F32 temp;
228 temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
229 temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
230 temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
231
232 // rotate the translation part by the new rotation
233 // (temporarily store in empty column of matrix)
234 U32 j;
235 for (j=0; j<3; j++)
236 {
237 mMatrix[j][VW] = mMatrix[VW][VX] * mMatrix[VX][j] +
238 mMatrix[VW][VY] * mMatrix[VY][j] +
239 mMatrix[VW][VZ] * mMatrix[VZ][j];
240 }
241
242 // negate and copy the temporary vector back to the tranlation row
243 mMatrix[VW][VX] = -mMatrix[VX][VW];
244 mMatrix[VW][VY] = -mMatrix[VY][VW];
245 mMatrix[VW][VZ] = -mMatrix[VZ][VW];
246
247 // zero the empty column again
248 mMatrix[VX][VW] = mMatrix[VY][VW] = mMatrix[VZ][VW] = 0.0f;
249
250 return *this;
251}
252
253LLVector4 LLMatrix4::getFwdRow4() const
254{
255 return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);
256}
257
258LLVector4 LLMatrix4::getLeftRow4() const
259{
260 return LLVector4(mMatrix[VY][VX], mMatrix[VY][VY], mMatrix[VY][VZ], mMatrix[VY][VW]);
261}
262
263LLVector4 LLMatrix4::getUpRow4() const
264{
265 return LLVector4(mMatrix[VZ][VX], mMatrix[VZ][VY], mMatrix[VZ][VZ], mMatrix[VZ][VW]);
266}
267
268// SJB: This code is correct for a logicly stored (non-transposed) matrix;
269// Our matrices are stored transposed, OpenGL style, so this generates the
270// INVERSE quaternion (-x, -y, -z, w)!
271// Because we use similar logic in LLQuaternion::getMatrix3,
272// we are internally consistant so everything works OK :)
273LLQuaternion LLMatrix4::quaternion() const
274{
275 LLQuaternion quat;
276 F32 tr, s, q[4];
277 U32 i, j, k;
278 U32 nxt[3] = {1, 2, 0};
279
280 tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2];
281
282 // check the diagonal
283 if (tr > 0.f)
284 {
285 s = (F32)sqrt (tr + 1.f);
286 quat.mQ[VS] = s / 2.f;
287 s = 0.5f / s;
288 quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s;
289 quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s;
290 quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s;
291 }
292 else
293 {
294 // diagonal is negative
295 i = 0;
296 if (mMatrix[1][1] > mMatrix[0][0])
297 i = 1;
298 if (mMatrix[2][2] > mMatrix[i][i])
299 i = 2;
300
301 j = nxt[i];
302 k = nxt[j];
303
304
305 s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f);
306
307 q[i] = s * 0.5f;
308
309 if (s != 0.f)
310 s = 0.5f / s;
311
312 q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s;
313 q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s;
314 q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s;
315
316 quat.setQuat(q);
317 }
318 return quat;
319}
320
321
322
323void LLMatrix4::initRows(const LLVector4 &row0,
324 const LLVector4 &row1,
325 const LLVector4 &row2,
326 const LLVector4 &row3)
327{
328 mMatrix[0][0] = row0.mV[0];
329 mMatrix[0][1] = row0.mV[1];
330 mMatrix[0][2] = row0.mV[2];
331 mMatrix[0][3] = row0.mV[3];
332
333 mMatrix[1][0] = row1.mV[0];
334 mMatrix[1][1] = row1.mV[1];
335 mMatrix[1][2] = row1.mV[2];
336 mMatrix[1][3] = row1.mV[3];
337
338 mMatrix[2][0] = row2.mV[0];
339 mMatrix[2][1] = row2.mV[1];
340 mMatrix[2][2] = row2.mV[2];
341 mMatrix[2][3] = row2.mV[3];
342
343 mMatrix[3][0] = row3.mV[0];
344 mMatrix[3][1] = row3.mV[1];
345 mMatrix[3][2] = row3.mV[2];
346 mMatrix[3][3] = row3.mV[3];
347}
348
349
350const LLMatrix4& LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
351{
352 LLMatrix3 mat(angle, x, y, z);
353 return initMatrix(mat);
354}
355
356
357const LLMatrix4& LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
358{
359 LLMatrix3 mat(angle, vec);
360 return initMatrix(mat);
361}
362
363
364const LLMatrix4& LLMatrix4::initRotation(const F32 roll, const F32 pitch, const F32 yaw)
365{
366 LLMatrix3 mat(roll, pitch, yaw);
367 return initMatrix(mat);
368}
369
370
371const LLMatrix4& LLMatrix4::initRotation(const LLQuaternion &q)
372{
373 LLMatrix3 mat(q);
374 return initMatrix(mat);
375}
376
377
378// Position and Rotation
379const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
380 const F32 tx, const F32 ty, const F32 tz)
381{
382 LLMatrix3 mat(angle, rx, ry, rz);
383 LLVector3 translation(tx, ty, tz);
384 initMatrix(mat);
385 setTranslation(translation);
386 return (*this);
387}
388
389const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
390{
391 LLMatrix3 mat(angle, axis);
392 initMatrix(mat);
393 setTranslation(translation);
394 return (*this);
395}
396
397const LLMatrix4& LLMatrix4::initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &translation)
398{
399 LLMatrix3 mat(roll, pitch, yaw);
400 initMatrix(mat);
401 setTranslation(translation);
402 return (*this);
403}
404
405/*
406const LLMatrix4& LLMatrix4::initRotTrans(const LLVector4 &fwd,
407 const LLVector4 &left,
408 const LLVector4 &up,
409 const LLVector4 &translation)
410{
411 LLMatrix3 mat(fwd, left, up);
412 initMatrix(mat);
413 setTranslation(translation);
414 return (*this);
415}
416*/
417
418const LLMatrix4& LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector4 &translation)
419{
420 LLMatrix3 mat(q);
421 initMatrix(mat);
422 setTranslation(translation);
423 return (*this);
424}
425
426const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos)
427{
428 F32 sx, sy, sz;
429 F32 xx, xy, xz, xw, yy, yz, yw, zz, zw;
430
431 sx = scale.mV[0];
432 sy = scale.mV[1];
433 sz = scale.mV[2];
434
435 xx = q.mQ[VX] * q.mQ[VX];
436 xy = q.mQ[VX] * q.mQ[VY];
437 xz = q.mQ[VX] * q.mQ[VZ];
438 xw = q.mQ[VX] * q.mQ[VW];
439
440 yy = q.mQ[VY] * q.mQ[VY];
441 yz = q.mQ[VY] * q.mQ[VZ];
442 yw = q.mQ[VY] * q.mQ[VW];
443
444 zz = q.mQ[VZ] * q.mQ[VZ];
445 zw = q.mQ[VZ] * q.mQ[VW];
446
447 mMatrix[0][0] = (1.f - 2.f * ( yy + zz )) *sx;
448 mMatrix[0][1] = ( 2.f * ( xy + zw )) *sx;
449 mMatrix[0][2] = ( 2.f * ( xz - yw )) *sx;
450
451 mMatrix[1][0] = ( 2.f * ( xy - zw )) *sy;
452 mMatrix[1][1] = (1.f - 2.f * ( xx + zz )) *sy;
453 mMatrix[1][2] = ( 2.f * ( yz + xw )) *sy;
454
455 mMatrix[2][0] = ( 2.f * ( xz + yw )) *sz;
456 mMatrix[2][1] = ( 2.f * ( yz - xw )) *sz;
457 mMatrix[2][2] = (1.f - 2.f * ( xx + yy )) *sz;
458
459 mMatrix[3][0] = pos.mV[0];
460 mMatrix[3][1] = pos.mV[1];
461 mMatrix[3][2] = pos.mV[2];
462 mMatrix[3][3] = 1.0;
463
464 // TODO -- should we set the translation portion to zero?
465 return (*this);
466}
467
468// Rotate exisitng mMatrix
469const LLMatrix4& LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
470{
471 LLVector4 vec4(x, y, z);
472 LLMatrix4 mat(angle, vec4);
473 *this *= mat;
474 return *this;
475}
476
477const LLMatrix4& LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
478{
479 LLMatrix4 mat(angle, vec);
480 *this *= mat;
481 return *this;
482}
483
484const LLMatrix4& LLMatrix4::rotate(const F32 roll, const F32 pitch, const F32 yaw)
485{
486 LLMatrix4 mat(roll, pitch, yaw);
487 *this *= mat;
488 return *this;
489}
490
491const LLMatrix4& LLMatrix4::rotate(const LLQuaternion &q)
492{
493 LLMatrix4 mat(q);
494 *this *= mat;
495 return *this;
496}
497
498
499const LLMatrix4& LLMatrix4::translate(const LLVector3 &vec)
500{
501 mMatrix[3][0] += vec.mV[0];
502 mMatrix[3][1] += vec.mV[1];
503 mMatrix[3][2] += vec.mV[2];
504 return (*this);
505}
506
507
508void LLMatrix4::setFwdRow(const LLVector3 &row)
509{
510 mMatrix[VX][VX] = row.mV[VX];
511 mMatrix[VX][VY] = row.mV[VY];
512 mMatrix[VX][VZ] = row.mV[VZ];
513}
514
515void LLMatrix4::setLeftRow(const LLVector3 &row)
516{
517 mMatrix[VY][VX] = row.mV[VX];
518 mMatrix[VY][VY] = row.mV[VY];
519 mMatrix[VY][VZ] = row.mV[VZ];
520}
521
522void LLMatrix4::setUpRow(const LLVector3 &row)
523{
524 mMatrix[VZ][VX] = row.mV[VX];
525 mMatrix[VZ][VY] = row.mV[VY];
526 mMatrix[VZ][VZ] = row.mV[VZ];
527}
528
529
530void LLMatrix4::setFwdCol(const LLVector3 &col)
531{
532 mMatrix[VX][VX] = col.mV[VX];
533 mMatrix[VY][VX] = col.mV[VY];
534 mMatrix[VZ][VX] = col.mV[VZ];
535}
536
537void LLMatrix4::setLeftCol(const LLVector3 &col)
538{
539 mMatrix[VX][VY] = col.mV[VX];
540 mMatrix[VY][VY] = col.mV[VY];
541 mMatrix[VZ][VY] = col.mV[VZ];
542}
543
544void LLMatrix4::setUpCol(const LLVector3 &col)
545{
546 mMatrix[VX][VZ] = col.mV[VX];
547 mMatrix[VY][VZ] = col.mV[VY];
548 mMatrix[VZ][VZ] = col.mV[VZ];
549}
550
551
552const LLMatrix4& LLMatrix4::setTranslation(const F32 tx, const F32 ty, const F32 tz)
553{
554 mMatrix[VW][VX] = tx;
555 mMatrix[VW][VY] = ty;
556 mMatrix[VW][VZ] = tz;
557 return (*this);
558}
559
560const LLMatrix4& LLMatrix4::setTranslation(const LLVector3 &translation)
561{
562 mMatrix[VW][VX] = translation.mV[VX];
563 mMatrix[VW][VY] = translation.mV[VY];
564 mMatrix[VW][VZ] = translation.mV[VZ];
565 return (*this);
566}
567
568const LLMatrix4& LLMatrix4::setTranslation(const LLVector4 &translation)
569{
570 mMatrix[VW][VX] = translation.mV[VX];
571 mMatrix[VW][VY] = translation.mV[VY];
572 mMatrix[VW][VZ] = translation.mV[VZ];
573 return (*this);
574}
575
576// LLMatrix3 Extraction and Setting
577LLMatrix3 LLMatrix4::getMat3() const
578{
579 LLMatrix3 retmat;
580
581 retmat.mMatrix[0][0] = mMatrix[0][0];
582 retmat.mMatrix[0][1] = mMatrix[0][1];
583 retmat.mMatrix[0][2] = mMatrix[0][2];
584
585 retmat.mMatrix[1][0] = mMatrix[1][0];
586 retmat.mMatrix[1][1] = mMatrix[1][1];
587 retmat.mMatrix[1][2] = mMatrix[1][2];
588
589 retmat.mMatrix[2][0] = mMatrix[2][0];
590 retmat.mMatrix[2][1] = mMatrix[2][1];
591 retmat.mMatrix[2][2] = mMatrix[2][2];
592
593 return retmat;
594}
595
596const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat)
597{
598 mMatrix[0][0] = mat.mMatrix[0][0];
599 mMatrix[0][1] = mat.mMatrix[0][1];
600 mMatrix[0][2] = mat.mMatrix[0][2];
601 mMatrix[0][3] = 0.f;
602
603 mMatrix[1][0] = mat.mMatrix[1][0];
604 mMatrix[1][1] = mat.mMatrix[1][1];
605 mMatrix[1][2] = mat.mMatrix[1][2];
606 mMatrix[1][3] = 0.f;
607
608 mMatrix[2][0] = mat.mMatrix[2][0];
609 mMatrix[2][1] = mat.mMatrix[2][1];
610 mMatrix[2][2] = mat.mMatrix[2][2];
611 mMatrix[2][3] = 0.f;
612
613 mMatrix[3][0] = 0.f;
614 mMatrix[3][1] = 0.f;
615 mMatrix[3][2] = 0.f;
616 mMatrix[3][3] = 1.f;
617 return (*this);
618}
619
620const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &translation)
621{
622 mMatrix[0][0] = mat.mMatrix[0][0];
623 mMatrix[0][1] = mat.mMatrix[0][1];
624 mMatrix[0][2] = mat.mMatrix[0][2];
625 mMatrix[0][3] = 0.f;
626
627 mMatrix[1][0] = mat.mMatrix[1][0];
628 mMatrix[1][1] = mat.mMatrix[1][1];
629 mMatrix[1][2] = mat.mMatrix[1][2];
630 mMatrix[1][3] = 0.f;
631
632 mMatrix[2][0] = mat.mMatrix[2][0];
633 mMatrix[2][1] = mat.mMatrix[2][1];
634 mMatrix[2][2] = mat.mMatrix[2][2];
635 mMatrix[2][3] = 0.f;
636
637 mMatrix[3][0] = translation.mV[0];
638 mMatrix[3][1] = translation.mV[1];
639 mMatrix[3][2] = translation.mV[2];
640 mMatrix[3][3] = 1.f;
641 return (*this);
642}
643
644// LLMatrix4 Operators
645
646
647/* Not implemented to help enforce code consistency with the syntax of
648 row-major notation. This is a Good Thing.
649LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b)
650{
651 // Operate "to the right" on column-vector b
652 LLVector4 vec;
653 vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] +
654 a.mMatrix[VY][VX] * b.mV[VY] +
655 a.mMatrix[VZ][VX] * b.mV[VZ] +
656 a.mMatrix[VW][VX] * b.mV[VW];
657
658 vec.mV[VY] = a.mMatrix[VX][VY] * b.mV[VX] +
659 a.mMatrix[VY][VY] * b.mV[VY] +
660 a.mMatrix[VZ][VY] * b.mV[VZ] +
661 a.mMatrix[VW][VY] * b.mV[VW];
662
663 vec.mV[VZ] = a.mMatrix[VX][VZ] * b.mV[VX] +
664 a.mMatrix[VY][VZ] * b.mV[VY] +
665 a.mMatrix[VZ][VZ] * b.mV[VZ] +
666 a.mMatrix[VW][VZ] * b.mV[VW];
667
668 vec.mV[VW] = a.mMatrix[VX][VW] * b.mV[VX] +
669 a.mMatrix[VY][VW] * b.mV[VY] +
670 a.mMatrix[VZ][VW] * b.mV[VZ] +
671 a.mMatrix[VW][VW] * b.mV[VW];
672 return vec;
673}
674*/
675
676
677LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b)
678{
679 // Operate "to the left" on row-vector a
680 LLVector4 vec;
681 vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +
682 a.mV[VY] * b.mMatrix[VY][VX] +
683 a.mV[VZ] * b.mMatrix[VZ][VX] +
684 a.mV[VW] * b.mMatrix[VW][VX];
685
686 vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +
687 a.mV[VY] * b.mMatrix[VY][VY] +
688 a.mV[VZ] * b.mMatrix[VZ][VY] +
689 a.mV[VW] * b.mMatrix[VW][VY];
690
691 vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +
692 a.mV[VY] * b.mMatrix[VY][VZ] +
693 a.mV[VZ] * b.mMatrix[VZ][VZ] +
694 a.mV[VW] * b.mMatrix[VW][VZ];
695
696 vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] +
697 a.mV[VY] * b.mMatrix[VY][VW] +
698 a.mV[VZ] * b.mMatrix[VZ][VW] +
699 a.mV[VW] * b.mMatrix[VW][VW];
700 return vec;
701}
702
703LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b)
704{
705 // Rotates but does not translate
706 // Operate "to the left" on row-vector a
707 LLVector4 vec;
708 vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +
709 a.mV[VY] * b.mMatrix[VY][VX] +
710 a.mV[VZ] * b.mMatrix[VZ][VX];
711
712 vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +
713 a.mV[VY] * b.mMatrix[VY][VY] +
714 a.mV[VZ] * b.mMatrix[VZ][VY];
715
716 vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +
717 a.mV[VY] * b.mMatrix[VY][VZ] +
718 a.mV[VZ] * b.mMatrix[VZ][VZ];
719
720// vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] +
721// a.mV[VY] * b.mMatrix[VY][VW] +
722// a.mV[VZ] * b.mMatrix[VZ][VW] +
723 vec.mV[VW] = a.mV[VW];
724 return vec;
725}
726
727LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b)
728{
729 // Rotates but does not translate
730 // Operate "to the left" on row-vector a
731 LLVector3 vec;
732 vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +
733 a.mV[VY] * b.mMatrix[VY][VX] +
734 a.mV[VZ] * b.mMatrix[VZ][VX];
735
736 vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +
737 a.mV[VY] * b.mMatrix[VY][VY] +
738 a.mV[VZ] * b.mMatrix[VZ][VY];
739
740 vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +
741 a.mV[VY] * b.mMatrix[VY][VZ] +
742 a.mV[VZ] * b.mMatrix[VZ][VZ];
743 return vec;
744}
745
746bool operator==(const LLMatrix4 &a, const LLMatrix4 &b)
747{
748 U32 i, j;
749 for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
750 {
751 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
752 {
753 if (a.mMatrix[j][i] != b.mMatrix[j][i])
754 return FALSE;
755 }
756 }
757 return TRUE;
758}
759
760bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b)
761{
762 U32 i, j;
763 for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
764 {
765 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
766 {
767 if (a.mMatrix[j][i] != b.mMatrix[j][i])
768 return TRUE;
769 }
770 }
771 return FALSE;
772}
773
774const LLMatrix4& operator*=(LLMatrix4 &a, F32 k)
775{
776 U32 i, j;
777 for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
778 {
779 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
780 {
781 a.mMatrix[j][i] *= k;
782 }
783 }
784 return a;
785}
786
787std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a)
788{
789 s << "{ "
790 << a.mMatrix[VX][VX] << ", "
791 << a.mMatrix[VX][VY] << ", "
792 << a.mMatrix[VX][VZ] << ", "
793 << a.mMatrix[VX][VW]
794 << "; "
795 << a.mMatrix[VY][VX] << ", "
796 << a.mMatrix[VY][VY] << ", "
797 << a.mMatrix[VY][VZ] << ", "
798 << a.mMatrix[VY][VW]
799 << "; "
800 << a.mMatrix[VZ][VX] << ", "
801 << a.mMatrix[VZ][VY] << ", "
802 << a.mMatrix[VZ][VZ] << ", "
803 << a.mMatrix[VZ][VW]
804 << "; "
805 << a.mMatrix[VW][VX] << ", "
806 << a.mMatrix[VW][VY] << ", "
807 << a.mMatrix[VW][VZ] << ", "
808 << a.mMatrix[VW][VW]
809 << " }";
810 return s;
811}
812
813