JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / javajs / util / M4.java
1 /*\r
2    Copyright (C) 1997,1998,1999\r
3    Kenji Hiranabe, Eiwa System Management, Inc.\r
4 \r
5    This program is free software.\r
6    Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),\r
7    conforming to the Java(TM) 3D API specification by Sun Microsystems.\r
8 \r
9    Permission to use, copy, modify, distribute and sell this software\r
10    and its documentation for any purpose is hereby granted without fee,\r
11    provided that the above copyright notice appear in all copies and\r
12    that both that copyright notice and this permission notice appear\r
13    in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.\r
14    makes no representations about the suitability of this software for any\r
15    purpose.  It is provided "AS IS" with NO WARRANTY.\r
16 */\r
17 package javajs.util;\r
18 \r
19 /**\r
20  * A single precision floating point 4 by 4 matrix.\r
21  * \r
22  * @author Kenji hiranabe\r
23  * \r
24  *         additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique\r
25  *         constructor and method names for the optimization of compiled\r
26  *         JavaScript using Java2Script\r
27  */\r
28 public class M4 extends M34 {\r
29 \r
30   /**\r
31    * The fourth element of the first row.\r
32    */\r
33   public float m03;\r
34 \r
35   /**\r
36    * The fourth element of the second row.\r
37    */\r
38   public float m13;\r
39 \r
40   /**\r
41    * The fourth element of the third row.\r
42    */\r
43   public float m23;\r
44 \r
45   /**\r
46    * The first element of the fourth row.\r
47    */\r
48   public float m30;\r
49 \r
50   /**\r
51    * The second element of the fourth row.\r
52    */\r
53   public float m31;\r
54 \r
55   /**\r
56    * The third element of the fourth row.\r
57    */\r
58   public float m32;\r
59 \r
60   /**\r
61    * The fourth element of the fourth row.\r
62    */\r
63   public float m33 = 0;\r
64 \r
65   /**\r
66    * all zeros\r
67    * @j2sIgnore\r
68    */\r
69   public M4() {\r
70   }\r
71   /**\r
72    * Constructs and initializes a Matrix4f from the specified 16 element array.\r
73    * this.m00 =v[0], this.m01=v[1], etc.\r
74    * \r
75    * @param v\r
76    *        the array of length 16 containing in order\r
77    * @return m\r
78    */\r
79   public static M4 newA16(float[] v) {\r
80     M4 m = new M4();\r
81     m.m00 = v[0];\r
82     m.m01 = v[1];\r
83     m.m02 = v[2];\r
84     m.m03 = v[3];\r
85 \r
86     m.m10 = v[4];\r
87     m.m11 = v[5];\r
88     m.m12 = v[6];\r
89     m.m13 = v[7];\r
90 \r
91     m.m20 = v[8];\r
92     m.m21 = v[9];\r
93     m.m22 = v[10];\r
94     m.m23 = v[11];\r
95 \r
96     m.m30 = v[12];\r
97     m.m31 = v[13];\r
98     m.m32 = v[14];\r
99     m.m33 = v[15];\r
100 \r
101     return m;\r
102   }\r
103 \r
104   /**\r
105    * Constructs a new matrix with the same values as the Matrix4f parameter.\r
106    * \r
107    * @param m1\r
108    *        the source matrix\r
109    * @return m\r
110    */\r
111   public static M4 newM4(M4 m1) {\r
112     M4 m = new M4();\r
113     if (m1 == null) {\r
114       m.setIdentity();\r
115       return m;\r
116     }\r
117     m.setToM3(m1);\r
118     m.m03 = m1.m03;\r
119     m.m13 = m1.m13;\r
120     m.m23 = m1.m23;\r
121     m.m30 = m1.m30;\r
122     m.m31 = m1.m31;\r
123     m.m32 = m1.m32;\r
124     m.m33 = m1.m33;\r
125     return m;\r
126   }\r
127 \r
128   /**\r
129    * Constructs and initializes a Matrix4f from the rotation matrix and\r
130    * translation.\r
131    * \r
132    * @param m1\r
133    *        The rotation matrix representing the rotational components\r
134    * @param t\r
135    *        The translational components of the matrix\r
136    * @return m\r
137    */\r
138   public static M4 newMV(M3 m1, T3 t) {\r
139     M4 m = new M4();\r
140     m.setMV(m1, t);\r
141     return m;\r
142   }\r
143 \r
144   /**\r
145    * Sets this matrix to all zeros.\r
146    */\r
147   public void setZero() {\r
148     clear33();\r
149     m03 = m13 = m23 = m30 = m31 = m32 = m33 = 0.0f;\r
150   }\r
151 \r
152   /**\r
153    * Sets this Matrix4f to identity.\r
154    */\r
155   public void setIdentity() {\r
156     setZero();\r
157     m00 = m11 = m22 = m33 = 1.0f;\r
158   }\r
159 \r
160   /**\r
161    * Sets the value of this matrix to a copy of the passed matrix m1.\r
162    * \r
163    * @param m1\r
164    *        the matrix to be copied\r
165    * @return this\r
166    */\r
167   public M4 setM4(M4 m1) {\r
168     setM33(m1);\r
169     m03 = m1.m03;\r
170     m13 = m1.m13;\r
171     m23 = m1.m23;\r
172     m30 = m1.m30;\r
173     m31 = m1.m31;\r
174     m32 = m1.m32;\r
175     m33 = m1.m33;\r
176     return this;\r
177   }\r
178 \r
179   /**\r
180    * Initializes a Matrix4f from the rotation matrix and translation.\r
181    * \r
182    * @param m1\r
183    *        The rotation matrix representing the rotational components\r
184    * @param t\r
185    *        The translational components of the matrix\r
186    */\r
187   public void setMV(M3 m1, T3 t) {\r
188     setM33(m1);\r
189     setTranslation(t);\r
190     m33 = 1;\r
191   }\r
192 \r
193   /**\r
194    * Sets the rotational component (upper 3x3) of this matrix to the matrix\r
195    * values in the single precision Matrix3f argument; the other elements of\r
196    * this matrix are initialized as if this were an identity matrix (ie, affine\r
197    * matrix with no translational component).\r
198    * \r
199    * @param m1\r
200    *        the 3x3 matrix\r
201    */\r
202   public void setToM3(M34 m1) {\r
203     setM33(m1);\r
204     m03 = m13 = m23 = m30 = m31 = m32 = 0.0f;\r
205     m33 = 1.0f;\r
206   }\r
207 \r
208   /**\r
209    * Sets the rotational component (upper 3x3) of this matrix \r
210    * to a rotation given by an axis angle\r
211    * \r
212    * @param a\r
213    *        the axis and angle to be converted\r
214    */\r
215   public void setToAA(A4 a) {\r
216     setIdentity();\r
217     setAA33(a);\r
218   }\r
219 \r
220   /**\r
221    * Sets the values in this Matrix4f equal to the row-major array parameter\r
222    * (ie, the first four elements of the array will be copied into the first row\r
223    * of this matrix, etc.).\r
224    * \r
225    * @param m\r
226    */\r
227   public void setA(float m[]) {\r
228     m00 = m[0];\r
229     m01 = m[1];\r
230     m02 = m[2];\r
231     m03 = m[3];\r
232     m10 = m[4];\r
233     m11 = m[5];\r
234     m12 = m[6];\r
235     m13 = m[7];\r
236     m20 = m[8];\r
237     m21 = m[9];\r
238     m22 = m[10];\r
239     m23 = m[11];\r
240     m30 = m[12];\r
241     m31 = m[13];\r
242     m32 = m[14];\r
243     m33 = m[15];\r
244   }\r
245 \r
246   /**\r
247    * Modifies the translational components of this matrix to the values of the\r
248    * Vector3f argument; the other values of this matrix are not modified.\r
249    * \r
250    * @param trans\r
251    *        the translational component\r
252    */\r
253   public void setTranslation(T3 trans) {\r
254     m03 = trans.x;\r
255     m13 = trans.y;\r
256     m23 = trans.z;\r
257   }\r
258 \r
259   /**\r
260    * Sets the specified element of this matrix4f to the value provided.\r
261    * \r
262    * @param row\r
263    *        the row number to be modified (zero indexed)\r
264    * @param col\r
265    *        the column number to be modified (zero indexed)\r
266    * @param v\r
267    *        the new value\r
268    */\r
269   public void setElement(int row, int col, float v) {\r
270     if (row < 3 && col < 3) {\r
271       set33(row, col, v);\r
272       return;\r
273     }\r
274     if (row > 3 || col > 3)\r
275       err();\r
276     switch (row) {\r
277     case 0:\r
278       m03 = v;\r
279       return;\r
280     case 1:\r
281       m13 = v;\r
282       return;\r
283     case 2:\r
284       m23 = v;\r
285       return;\r
286     }\r
287     switch (col) {\r
288     case 0:\r
289       m30 = v;\r
290       return;\r
291     case 1:\r
292       m31 = v;\r
293       return;\r
294     case 2:\r
295       m32 = v;\r
296       return;\r
297     case 3:\r
298       m33 = v;\r
299       return;\r
300     }\r
301   }\r
302 \r
303   /**\r
304    * Retrieves the value at the specified row and column of this matrix.\r
305    * \r
306    * @param row\r
307    *        the row number to be retrieved (zero indexed)\r
308    * @param col\r
309    *        the column number to be retrieved (zero indexed)\r
310    * @return the value at the indexed element\r
311    */\r
312   public float getElement(int row, int col) {\r
313     if (row < 3 && col < 3)\r
314       return get33(row, col);\r
315     if (row > 3 || col > 3) {\r
316       err();\r
317       return 0;\r
318     }\r
319     switch (row) {\r
320     case 0:\r
321       return m03;\r
322     case 1:\r
323       return m13;\r
324     case 2:\r
325       return m23;\r
326     default:\r
327       switch (col) {\r
328       case 0:\r
329         return m30;\r
330       case 1:\r
331         return m31;\r
332       case 2:\r
333         return m32;\r
334       default:\r
335         return m33;\r
336       }\r
337     }\r
338   }\r
339 \r
340   /**\r
341    * Retrieves the translational components of this matrix.\r
342    * \r
343    * @param trans\r
344    *        the vector that will receive the translational component\r
345    */\r
346   public void getTranslation(T3 trans) {\r
347     trans.x = m03;\r
348     trans.y = m13;\r
349     trans.z = m23;\r
350   }\r
351 \r
352   /**\r
353    * Gets the upper 3x3 values of this matrix and places them into the matrix\r
354    * m1.\r
355    * \r
356    * @param m1\r
357    *        The matrix that will hold the values\r
358    */\r
359   public void getRotationScale(M3 m1) {\r
360     m1.m00 = m00;\r
361     m1.m01 = m01;\r
362     m1.m02 = m02;\r
363     m1.m10 = m10;\r
364     m1.m11 = m11;\r
365     m1.m12 = m12;\r
366     m1.m20 = m20;\r
367     m1.m21 = m21;\r
368     m1.m22 = m22;\r
369   }\r
370 \r
371   /**\r
372    * Replaces the upper 3x3 matrix values of this matrix with the values in the\r
373    * matrix m1.\r
374    * \r
375    * @param m1\r
376    *        The matrix that will be the new upper 3x3\r
377    */\r
378   public void setRotationScale(M3 m1) {\r
379     m00 = m1.m00;\r
380     m01 = m1.m01;\r
381     m02 = m1.m02;\r
382     m10 = m1.m10;\r
383     m11 = m1.m11;\r
384     m12 = m1.m12;\r
385     m20 = m1.m20;\r
386     m21 = m1.m21;\r
387     m22 = m1.m22;\r
388   }\r
389 \r
390   /**\r
391    * Sets the specified row of this matrix4f to the four values provided.\r
392    * \r
393    * @param row\r
394    *        the row number to be modified (zero indexed)\r
395    * @param v\r
396    *        the replacement row\r
397    */\r
398   public void setRowA(int row, float v[]) {\r
399     if (row < 3)\r
400       setRow33(row, v);\r
401     switch (row) {\r
402     case 0:\r
403       m03 = v[3];\r
404       return;\r
405     case 1:\r
406       m13 = v[3];\r
407       return;\r
408     case 2:\r
409       m23 = v[3];\r
410       return;\r
411     case 3:\r
412       m30 = v[0];\r
413       m31 = v[1];\r
414       m32 = v[2];\r
415       m33 = v[3];\r
416       return;\r
417     }\r
418     err();\r
419   }\r
420 \r
421   /**\r
422    * Copies the matrix values in the specified row into the array parameter.\r
423    * \r
424    * @param row\r
425    *        the matrix row\r
426    * @param v\r
427    *        The array into which the matrix row values will be copied\r
428    */\r
429   @Override\r
430   public void getRow(int row, float v[]) {\r
431     if (row < 3)\r
432       getRow33(row, v);\r
433     switch (row) {\r
434     case 0:\r
435       v[3] = m03;\r
436       return;\r
437     case 1:\r
438       v[3] = m13;\r
439       return;\r
440     case 2:\r
441       v[3] = m23;\r
442       return;\r
443     case 3:\r
444       v[0] = m30;\r
445       v[1] = m31;\r
446       v[2] = m32;\r
447       v[3] = m33;\r
448       return;\r
449     }\r
450     err();\r
451   }\r
452 \r
453   /**\r
454    * Sets the specified column of this matrix4f to the four values provided.\r
455    * \r
456    * @param column\r
457    *        the column number to be modified (zero indexed)\r
458    * @param x\r
459    *        the first row element\r
460    * @param y\r
461    *        the second row element\r
462    * @param z\r
463    *        the third row element\r
464    * @param w\r
465    *        the fourth row element\r
466    */\r
467   public void setColumn4(int column, float x, float y, float z, float w) {\r
468     if (column == 0) {\r
469       m00 = x;\r
470       m10 = y;\r
471       m20 = z;\r
472       m30 = w;\r
473     } else if (column == 1) {\r
474       m01 = x;\r
475       m11 = y;\r
476       m21 = z;\r
477       m31 = w;\r
478     } else if (column == 2) {\r
479       m02 = x;\r
480       m12 = y;\r
481       m22 = z;\r
482       m32 = w;\r
483     } else if (column == 3) {\r
484       m03 = x;\r
485       m13 = y;\r
486       m23 = z;\r
487       m33 = w;\r
488     } else {\r
489       err();\r
490     }\r
491   }\r
492 \r
493   /**\r
494    * Sets the specified column of this matrix4f to the four values provided.\r
495    * \r
496    * @param column\r
497    *        the column number to be modified (zero indexed)\r
498    * @param v\r
499    *        the replacement column\r
500    */\r
501   public void setColumnA(int column, float v[]) {\r
502     if (column < 3)\r
503       setColumn33(column, v);\r
504     switch (column) {\r
505     case 0:\r
506       m30 = v[3];\r
507       return;\r
508     case 1:\r
509       m31 = v[3];\r
510       return;\r
511     case 2:\r
512       m32 = v[3];\r
513       return;\r
514     case 3:\r
515       m03 = v[0];\r
516       m13 = v[1];\r
517       m23 = v[2];\r
518       m33 = v[3];\r
519       return;\r
520     default:\r
521       err();\r
522     }\r
523   }\r
524 \r
525   /**\r
526    * Copies the matrix values in the specified column into the array parameter.\r
527    * \r
528    * @param column\r
529    *        the matrix column\r
530    * @param v\r
531    *        The array into which the matrix column values will be copied\r
532    */\r
533   public void getColumn(int column, float v[]) {\r
534     if (column < 3)\r
535       getColumn33(column, v);\r
536     switch (column) {\r
537     case 0:\r
538       v[3] = m30;\r
539       return;\r
540     case 1:\r
541       v[3] = m31;\r
542       return;\r
543     case 2:\r
544       v[3] = m32;\r
545       return;\r
546     case 3:\r
547       v[0] = m03;\r
548       v[1] = m13;\r
549       v[2] = m23;\r
550       v[3] = m33;\r
551       return;\r
552     default:\r
553       err();\r
554     }\r
555   }\r
556 \r
557   /**\r
558    * Sets the value of this matrix to the matrix difference of itself and matrix\r
559    * m1 (this = this - m1).\r
560    * \r
561    * @param m1\r
562    *        the other matrix\r
563    */\r
564   public void sub(M4 m1) {\r
565     sub33(m1);\r
566     m03 -= m1.m03;\r
567     m13 -= m1.m13;\r
568     m23 -= m1.m23;\r
569     m30 -= m1.m30;\r
570     m31 -= m1.m31;\r
571     m32 -= m1.m32;\r
572     m33 -= m1.m33;\r
573   }\r
574 \r
575   /**\r
576    * Sets the value of this matrix to its transpose.\r
577    */\r
578   public void transpose() {\r
579     transpose33();\r
580     float tmp = m03;\r
581     m03 = m30;\r
582     m30 = tmp;\r
583 \r
584     tmp = m13;\r
585     m13 = m31;\r
586     m31 = tmp;\r
587 \r
588     tmp = m23;\r
589     m23 = m32;\r
590     m32 = tmp;\r
591   }\r
592 \r
593   /**\r
594    * Sets the value of this matrix to its inverse.\r
595    * @return this\r
596    */\r
597   public M4 invert() {\r
598     float s = determinant4();\r
599     if (s == 0.0)\r
600       return this;\r
601     s = 1 / s;\r
602     // alias-safe way.\r
603     // less *,+,- calculation than expanded expression.\r
604     set(m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13\r
605         * (m21 * m32 - m22 * m31), m21 * (m02 * m33 - m03 * m32) + m22\r
606         * (m03 * m31 - m01 * m33) + m23 * (m01 * m32 - m02 * m31), m31\r
607         * (m02 * m13 - m03 * m12) + m32 * (m03 * m11 - m01 * m13) + m33\r
608         * (m01 * m12 - m02 * m11), m01 * (m13 * m22 - m12 * m23) + m02\r
609         * (m11 * m23 - m13 * m21) + m03 * (m12 * m21 - m11 * m22),\r
610 \r
611     m12 * (m20 * m33 - m23 * m30) + m13 * (m22 * m30 - m20 * m32) + m10\r
612         * (m23 * m32 - m22 * m33), m22 * (m00 * m33 - m03 * m30) + m23\r
613         * (m02 * m30 - m00 * m32) + m20 * (m03 * m32 - m02 * m33), m32\r
614         * (m00 * m13 - m03 * m10) + m33 * (m02 * m10 - m00 * m12) + m30\r
615         * (m03 * m12 - m02 * m13), m02 * (m13 * m20 - m10 * m23) + m03\r
616         * (m10 * m22 - m12 * m20) + m00 * (m12 * m23 - m13 * m22),\r
617 \r
618     m13 * (m20 * m31 - m21 * m30) + m10 * (m21 * m33 - m23 * m31) + m11\r
619         * (m23 * m30 - m20 * m33), m23 * (m00 * m31 - m01 * m30) + m20\r
620         * (m01 * m33 - m03 * m31) + m21 * (m03 * m30 - m00 * m33), m33\r
621         * (m00 * m11 - m01 * m10) + m30 * (m01 * m13 - m03 * m11) + m31\r
622         * (m03 * m10 - m00 * m13), m03 * (m11 * m20 - m10 * m21) + m00\r
623         * (m13 * m21 - m11 * m23) + m01 * (m10 * m23 - m13 * m20),\r
624 \r
625     m10 * (m22 * m31 - m21 * m32) + m11 * (m20 * m32 - m22 * m30) + m12\r
626         * (m21 * m30 - m20 * m31), m20 * (m02 * m31 - m01 * m32) + m21\r
627         * (m00 * m32 - m02 * m30) + m22 * (m01 * m30 - m00 * m31), m30\r
628         * (m02 * m11 - m01 * m12) + m31 * (m00 * m12 - m02 * m10) + m32\r
629         * (m01 * m10 - m00 * m11), m00 * (m11 * m22 - m12 * m21) + m01\r
630         * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20));\r
631     scale(s);\r
632     return this;\r
633   }\r
634 \r
635   /**\r
636    * Sets 16 values\r
637    * \r
638    * @param m00\r
639    * @param m01\r
640    * @param m02\r
641    * @param m03\r
642    * @param m10\r
643    * @param m11\r
644    * @param m12\r
645    * @param m13\r
646    * @param m20\r
647    * @param m21\r
648    * @param m22\r
649    * @param m23\r
650    * @param m30\r
651    * @param m31\r
652    * @param m32\r
653    * @param m33\r
654    */\r
655   private void set(float m00, float m01, float m02, float m03, float m10,\r
656                    float m11, float m12, float m13, float m20, float m21,\r
657                    float m22, float m23, float m30, float m31, float m32,\r
658                    float m33) {\r
659     this.m00 = m00;\r
660     this.m01 = m01;\r
661     this.m02 = m02;\r
662     this.m03 = m03;\r
663     this.m10 = m10;\r
664     this.m11 = m11;\r
665     this.m12 = m12;\r
666     this.m13 = m13;\r
667     this.m20 = m20;\r
668     this.m21 = m21;\r
669     this.m22 = m22;\r
670     this.m23 = m23;\r
671     this.m30 = m30;\r
672     this.m31 = m31;\r
673     this.m32 = m32;\r
674     this.m33 = m33;\r
675   }\r
676   /**\r
677    * Computes the determinant of this matrix.\r
678    * \r
679    * @return the determinant of the matrix\r
680    */\r
681   public float determinant4() {\r
682     // less *,+,- calculation than expanded expression.\r
683     return (m00 * m11 - m01 * m10) * (m22 * m33 - m23 * m32)\r
684         - (m00 * m12 - m02 * m10) * (m21 * m33 - m23 * m31)\r
685         + (m00 * m13 - m03 * m10) * (m21 * m32 - m22 * m31)\r
686         + (m01 * m12 - m02 * m11) * (m20 * m33 - m23 * m30)\r
687         - (m01 * m13 - m03 * m11) * (m20 * m32 - m22 * m30)\r
688         + (m02 * m13 - m03 * m12) * (m20 * m31 - m21 * m30);\r
689 \r
690   }\r
691 \r
692   /**\r
693    * Multiplies each element of this matrix by a scalar.\r
694    * \r
695    * @param scalar\r
696    *        The scalar multiplier.\r
697    */\r
698   private void scale(float scalar) {\r
699     mul33(scalar);\r
700     m03 *= scalar;\r
701     m13 *= scalar;\r
702     m23 *= scalar;\r
703     m30 *= scalar;\r
704     m31 *= scalar;\r
705     m32 *= scalar;\r
706     m33 *= scalar;\r
707   }\r
708 \r
709   /**\r
710    * Sets the value of this matrix to the result of multiplying itself with\r
711    * matrix m1.\r
712    * \r
713    * @param m1\r
714    *        the other matrix\r
715    */\r
716   public void mul(M4 m1) {\r
717     mul2(this, m1);\r
718   }\r
719 \r
720   /**\r
721    * Sets the value of this matrix to the result of multiplying the two argument\r
722    * matrices together.\r
723    * \r
724    * @param m1\r
725    *        the first matrix\r
726    * @param m2\r
727    *        the second matrix\r
728    */\r
729   public void mul2(M4 m1, M4 m2) {\r
730     // alias-safe way.\r
731     set(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30,\r
732         m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31,\r
733         m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32,\r
734         m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33,\r
735 \r
736         m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30,\r
737         m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31,\r
738         m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32,\r
739         m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33,\r
740 \r
741         m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30,\r
742         m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31,\r
743         m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32,\r
744         m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33,\r
745 \r
746         m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30,\r
747         m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31,\r
748         m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32,\r
749         m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33);\r
750   }\r
751 \r
752   /**\r
753    * Transform the vector vec using this Matrix4f and place the result back into\r
754    * vec.\r
755    * \r
756    * @param vec\r
757    *        the single precision vector to be transformed\r
758    */\r
759   public void transform(T4 vec) {\r
760     transform2(vec, vec);\r
761   }\r
762 \r
763   /**\r
764    * Transform the vector vec using this Matrix4f and place the result into\r
765    * vecOut.\r
766    * \r
767    * @param vec\r
768    *        the single precision vector to be transformed\r
769    * @param vecOut\r
770    *        the vector into which the transformed values are placed\r
771    */\r
772   public void transform2(T4 vec, T4 vecOut) {\r
773     // alias-safe\r
774     vecOut.set4(m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, m10\r
775         * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, m20 * vec.x + m21\r
776         * vec.y + m22 * vec.z + m23 * vec.w, m30 * vec.x + m31 * vec.y + m32\r
777         * vec.z + m33 * vec.w);\r
778   }\r
779 \r
780   /**\r
781    * Transforms the point parameter with this Matrix4f and places the result\r
782    * back into point. The fourth element of the point input parameter is assumed\r
783    * to be one.\r
784    * \r
785    * @param point\r
786    *        the input point to be transformed.\r
787    */\r
788   public void rotTrans(T3 point) {\r
789     rotTrans2(point, point);\r
790   }\r
791 \r
792   /**\r
793    * Transforms the point parameter with this Matrix4f and places the result\r
794    * into pointOut. The fourth element of the point input parameter is assumed to\r
795    * be one. point may be pointOut\r
796    * \r
797    * @param point\r
798    *        the input point to be transformed.\r
799    * @param pointOut\r
800    *        the transformed point\r
801    * @return pointOut\r
802    */\r
803   public T3 rotTrans2(T3 point, T3 pointOut) {\r
804       pointOut.set(\r
805           m00 * point.x + m01 * point.y + m02 * point.z + m03, \r
806           m10 * point.x + m11 * point.y + m12 * point.z + m13, \r
807           m20 * point.x + m21 * point.y + m22 * point.z + m23);\r
808       return pointOut;\r
809   }\r
810 \r
811   /**\r
812    * Sets the value of this matrix to a rotation matrix about the w axis by the\r
813    * passed angle.\r
814    * \r
815    * @param angle\r
816    *        the angle to rotate about the W axis in radians\r
817    * @return this\r
818    */\r
819   public M4 setAsXYRotation(float angle) {\r
820     setIdentity();\r
821     double c = Math.cos(angle);\r
822     double s = Math.sin(angle);\r
823     m22 = (float) c;\r
824     m23 = (float) -s;\r
825     m32 = (float) s;\r
826     m33 = (float) c;\r
827     return this;\r
828   }\r
829 \r
830   /**\r
831    * Sets the value of this matrix to a rotation matrix about the w axis by the\r
832    * passed angle.\r
833    * \r
834    * @param angle\r
835    *        the angle to rotate about the W axis in radians\r
836    * @return this\r
837    */\r
838   public M4 setAsYZRotation(float angle) {\r
839     setIdentity();\r
840     double c = Math.cos(angle);\r
841     double s = Math.sin(angle);\r
842     m00 = (float) c;\r
843     m03 = (float) -s;\r
844     m30 = (float) s;\r
845     m33 = (float) c;\r
846     return this;\r
847   }\r
848 \r
849   /**\r
850    * Sets the value of this matrix to a rotation matrix about the w axis by the\r
851    * passed angle.\r
852    * \r
853    * @param angle\r
854    *        the angle to rotate about the W axis in radians\r
855    * @return this\r
856    */\r
857   public M4 setAsXZRotation(float angle) {\r
858     setIdentity();\r
859     double c = Math.cos(angle);\r
860     double s = Math.sin(angle);\r
861     m11 = (float) c;\r
862     m13 = (float) -s;\r
863     m31 = (float) s;\r
864     m33 = (float) c;\r
865     return this;\r
866   }\r
867 \r
868   /**\r
869    * Returns true if the Object o is of type Matrix4f and all of the data\r
870    * members of t1 are equal to the corresponding data members in this Matrix4f.\r
871    * \r
872    * @param o\r
873    *        the object with which the comparison is made.\r
874    */\r
875   @Override\r
876   public boolean equals(Object o) {\r
877     if (!(o instanceof M4))\r
878       return false;\r
879     M4 m = (M4) o;\r
880     return (this.m00 == m.m00 && this.m01 == m.m01 && this.m02 == m.m02\r
881         && this.m03 == m.m03 && this.m10 == m.m10 && this.m11 == m.m11\r
882         && this.m12 == m.m12 && this.m13 == m.m13 && this.m20 == m.m20\r
883         && this.m21 == m.m21 && this.m22 == m.m22 && this.m23 == m.m23\r
884         && this.m30 == m.m30 && this.m31 == m.m31 && this.m32 == m.m32 && this.m33 == m.m33);\r
885   }\r
886 \r
887   /**\r
888    * Returns a hash number based on the data values in this object. Two\r
889    * different Matrix4f objects with identical data values (ie, returns true for\r
890    * equals(Matrix4f) ) will return the same hash number. Two objects with\r
891    * different data members may return the same hash value, although this is not\r
892    * likely.\r
893    * \r
894    * @return the integer hash value\r
895    */\r
896   @Override\r
897   public int hashCode() {\r
898     return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)\r
899         ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m03)\r
900         ^ T3.floatToIntBits0(m10) ^ T3.floatToIntBits0(m11)\r
901         ^ T3.floatToIntBits0(m12) ^ T3.floatToIntBits0(m13)\r
902         ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)\r
903         ^ T3.floatToIntBits0(m22) ^ T3.floatToIntBits0(m23)\r
904         ^ T3.floatToIntBits0(m30) ^ T3.floatToIntBits0(m31)\r
905         ^ T3.floatToIntBits0(m32) ^ T3.floatToIntBits0(m33);\r
906   }\r
907 \r
908   /**\r
909    * Returns a string that contains the values of this Matrix4f.\r
910    * \r
911    * @return the String representation\r
912    */\r
913   @Override\r
914   public String toString() {\r
915     return "[\n  [" + m00 + "\t" + m01 + "\t" + m02 + "\t" + m03 + "]"\r
916         + "\n  [" + m10 + "\t" + m11 + "\t" + m12 + "\t" + m13 + "]" + "\n  ["\r
917         + m20 + "\t" + m21 + "\t" + m22 + "\t" + m23 + "]" + "\n  [" + m30\r
918         + "\t" + m31 + "\t" + m32 + "\t" + m33 + "] ]";\r
919   }\r
920   public M4 round(float f) {\r
921     m00 = rnd(m00, f);\r
922     m01 = rnd(m01, f);\r
923     m02 = rnd(m02, f);\r
924     m03 = rnd(m03, f);\r
925     m10 = rnd(m10, f);\r
926     m11 = rnd(m11, f);\r
927     m12 = rnd(m12, f);\r
928     m13 = rnd(m13, f);\r
929     m20 = rnd(m20, f);\r
930     m21 = rnd(m21, f);\r
931     m22 = rnd(m22, f);\r
932     m23 = rnd(m23, f);\r
933     m30 = rnd(m30, f);\r
934     m31 = rnd(m31, f);\r
935     m32 = rnd(m32, f);\r
936     m33 = rnd(m33, f);\r
937     return this;\r
938   }\r
939 \r
940   private float rnd(float n, float f) {\r
941     return (Math.abs(n) < f ? 0 : n);\r
942   }\r
943 }\r