]> gerrit.simantics Code Review - simantics/3d.git/blob - javax.vecmath/src/javax/vecmath/Matrix3f.java
Included old javax.vecmath 1.5.2 to org.simantics.g3d.feature
[simantics/3d.git] / javax.vecmath / src / javax / vecmath / Matrix3f.java
1 /*
2  * $RCSfile: Matrix3f.java,v $
3  *
4  * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6  *
7  * This code is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 only, as
9  * published by the Free Software Foundation.  Sun designates this
10  * particular file as subject to the "Classpath" exception as provided
11  * by Sun in the LICENSE file that accompanied this code.
12  *
13  * This code is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  * version 2 for more details (a copy is included in the LICENSE file that
17  * accompanied this code).
18  *
19  * You should have received a copy of the GNU General Public License version
20  * 2 along with this work; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24  * CA 95054 USA or visit www.sun.com if you need additional information or
25  * have any questions.
26  *
27  * $Revision: 1.8 $
28  * $Date: 2008/02/28 20:18:50 $
29  * $State: Exp $
30  */
31
32 package javax.vecmath;
33
34 import java.lang.Math;
35
36 /**
37  * A single precision floating point 3 by 3 matrix.
38  * Primarily to support 3D rotations.
39  *
40  */
41 public class Matrix3f implements java.io.Serializable, Cloneable {
42
43   // Compatible with 1.1
44   static final long serialVersionUID = 329697160112089834L;
45
46   /** 
47     * The first matrix element in the first row.
48     */
49     public      float   m00;
50
51   /** 
52     * The second matrix element in the first row.
53     */
54     public      float   m01;
55
56   /** 
57     * The third matrix element in the first row.
58     */
59     public      float   m02;
60
61   /** 
62     * The first matrix element in the second row.
63     */
64     public      float   m10;
65
66   /** 
67     * The second matrix element in the second row.
68     */
69     public      float   m11;
70
71   /** 
72     * The third matrix element in the second row.
73     */
74     public      float   m12;
75
76   /** 
77     * The first matrix element in the third row.
78     */
79     public      float   m20;
80
81   /** 
82     * The second matrix element in the third row.
83     */
84     public      float   m21;
85
86   /** 
87     * The third matrix element in the third row.
88     */
89     public      float   m22;
90     /*
91     double[]    tmp       = new double[9];  // scratch matrix
92     double[]    tmp_rot   = new double[9];  // scratch matrix
93     double[]    tmp_scale = new double[3];  // scratch matrix
94     */
95     private static final double EPS = 1.0E-8;
96
97   
98
99     /**
100      * Constructs and initializes a Matrix3f from the specified nine values.
101      * @param m00 the [0][0] element
102      * @param m01 the [0][1] element
103      * @param m02 the [0][2] element
104      * @param m10 the [1][0] element
105      * @param m11 the [1][1] element
106      * @param m12 the [1][2] element
107      * @param m20 the [2][0] element
108      * @param m21 the [2][1] element
109      * @param m22 the [2][2] element
110      */
111     public Matrix3f(float m00, float m01, float m02,
112                     float m10, float m11, float m12,
113                     float m20, float m21, float m22)
114     {
115         this.m00 = m00;
116         this.m01 = m01;
117         this.m02 = m02;
118
119         this.m10 = m10;
120         this.m11 = m11;
121         this.m12 = m12;
122
123         this.m20 = m20;
124         this.m21 = m21;
125         this.m22 = m22;
126
127     }
128
129     /**
130      * Constructs and initializes a Matrix3f from the specified 
131      * nine-element array.   this.m00 =v[0], this.m01=v[1], etc.
132      * @param v the array of length 9 containing in order
133      */
134     public Matrix3f(float[] v)
135     {
136         this.m00 = v[ 0];
137         this.m01 = v[ 1];
138         this.m02 = v[ 2];
139
140         this.m10 = v[ 3];
141         this.m11 = v[ 4];
142         this.m12 = v[ 5];
143
144         this.m20 = v[ 6];
145         this.m21 = v[ 7];
146         this.m22 = v[ 8];
147
148     }
149
150    /**   
151      *  Constructs a new matrix with the same values as the 
152      *  Matrix3d parameter.
153      *  @param m1  the source matrix
154      */  
155    public Matrix3f(Matrix3d m1) 
156    { 
157         this.m00 = (float)m1.m00;
158         this.m01 = (float)m1.m01;
159         this.m02 = (float)m1.m02;
160  
161         this.m10 = (float)m1.m10;
162         this.m11 = (float)m1.m11;
163         this.m12 = (float)m1.m12;
164  
165         this.m20 = (float)m1.m20;
166         this.m21 = (float)m1.m21;
167         this.m22 = (float)m1.m22;
168
169    } 
170  
171  
172    /**
173      *  Constructs a new matrix with the same values as the
174      *  Matrix3f parameter.
175      *  @param m1  the source matrix
176      */  
177    public Matrix3f(Matrix3f m1)
178    {
179         this.m00 = m1.m00;
180         this.m01 = m1.m01;
181         this.m02 = m1.m02;
182  
183         this.m10 = m1.m10;
184         this.m11 = m1.m11;
185         this.m12 = m1.m12;
186  
187         this.m20 = m1.m20;
188         this.m21 = m1.m21;
189         this.m22 = m1.m22;
190
191    }
192  
193
194     /**
195      * Constructs and initializes a Matrix3f to all zeros.
196      */
197     public Matrix3f()
198     {
199         this.m00 = (float) 0.0;
200         this.m01 = (float) 0.0;
201         this.m02 = (float) 0.0;
202
203         this.m10 = (float) 0.0;
204         this.m11 = (float) 0.0;
205         this.m12 = (float) 0.0;
206
207         this.m20 = (float) 0.0;
208         this.m21 = (float) 0.0;
209         this.m22 = (float) 0.0;
210
211     }
212
213    /**
214      * Returns a string that contains the values of this Matrix3f.
215      * @return the String representation
216      */
217     public String toString() {
218       return
219         this.m00 + ", " + this.m01 + ", " + this.m02 + "\n" +
220         this.m10 + ", " + this.m11 + ", " + this.m12 + "\n" +
221         this.m20 + ", " + this.m21 + ", " + this.m22 + "\n";
222     }
223
224     /**
225      * Sets this Matrix3f to identity.
226      */
227     public final void setIdentity()
228     {
229         this.m00 = (float) 1.0;
230         this.m01 = (float) 0.0;
231         this.m02 = (float) 0.0;
232
233         this.m10 = (float) 0.0;
234         this.m11 = (float) 1.0;
235         this.m12 = (float) 0.0;
236
237         this.m20 = (float) 0.0;
238         this.m21 = (float) 0.0;
239         this.m22 = (float) 1.0;
240     }
241
242    /**
243      * Sets the scale component of the current matrix by factoring
244      * out the current scale (by doing an SVD) and multiplying by 
245      * the new scale.
246      * @param scale  the new scale amount
247      */
248     public final void setScale(float scale)
249     {
250         double[]    tmp_rot = new double[9];  // scratch matrix
251         double[]    tmp_scale = new double[3];  // scratch matrix
252         
253         getScaleRotate( tmp_scale, tmp_rot );
254  
255         this.m00 = (float)(tmp_rot[0] * scale);
256         this.m01 = (float)(tmp_rot[1] * scale);
257         this.m02 = (float)(tmp_rot[2] * scale);
258  
259         this.m10 = (float)(tmp_rot[3] * scale);
260         this.m11 = (float)(tmp_rot[4] * scale);
261         this.m12 = (float)(tmp_rot[5] * scale);
262  
263         this.m20 = (float)(tmp_rot[6] * scale);
264         this.m21 = (float)(tmp_rot[7] * scale);
265         this.m22 = (float)(tmp_rot[8] * scale);
266
267     }
268
269     /**
270      * Sets the specified element of this matrix3f to the value provided.
271      * @param row the row number to be modified (zero indexed)
272      * @param column the column number to be modified (zero indexed)
273      * @param value the new value
274      */
275     public final void setElement(int row, int column, float value)
276     {
277         switch (row) 
278           {
279           case 0:
280             switch(column)
281               {
282               case 0:
283                 this.m00 = value;
284                 break;
285               case 1:
286                 this.m01 = value;
287                 break;
288               case 2:
289                 this.m02 = value;
290                 break;
291               default:
292                 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
293               }
294             break;
295
296           case 1:
297             switch(column) 
298               {
299               case 0:
300                 this.m10 = value;
301                 break;
302               case 1:
303                 this.m11 = value;
304                 break;
305               case 2:
306                 this.m12 = value;
307                 break;
308               default:
309                 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
310               }
311             break;
312           
313           case 2:
314             switch(column) 
315               {
316               case 0:
317                 this.m20 = value;
318                 break;
319               case 1:
320                 this.m21 = value;
321                 break;
322               case 2:
323                 this.m22 = value;
324                 break;
325               default:
326
327                 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
328               }
329             break;
330
331           default:
332                 throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f0"));
333           }
334     }
335
336     /**
337      * Copies the matrix values in the specified row into the vector parameter. 
338      * @param row  the matrix row
339      * @param v    the vector into which the matrix row values will be copied
340      */
341     public final void getRow(int row, Vector3f v) {
342          if( row == 0 ) {
343            v.x = m00;
344            v.y = m01;
345            v.z = m02;
346         } else if(row == 1) {
347            v.x = m10;
348            v.y = m11;
349            v.z = m12;
350         } else if(row == 2) {
351            v.x = m20;
352            v.y = m21;
353            v.z = m22;
354         } else {
355           throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f1"));
356         }
357
358     }
359
360     /**
361      * Copies the matrix values in the specified row into the array parameter. 
362      * @param row  the matrix row
363      * @param v    the array into which the matrix row values will be copied 
364      */  
365     public final void getRow(int row, float v[]) {
366         if( row == 0 ) {
367            v[0] = m00; 
368            v[1] = m01;
369            v[2] = m02;
370         } else if(row == 1) {
371            v[0] = m10;
372            v[1] = m11;
373            v[2] = m12;
374         } else if(row == 2) {
375            v[0] = m20;
376            v[1] = m21;
377            v[2] = m22;
378         } else {
379           throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f1"));
380         }
381
382     }
383
384     /**
385      * Copies the matrix values in the specified column into the vector 
386      * parameter.
387      * @param column  the matrix column
388      * @param v    the vector into which the matrix row values will be copied
389      */  
390     public final void getColumn(int column, Vector3f v) {
391         if( column == 0 ) {
392            v.x = m00;
393            v.y = m10;
394            v.z = m20;
395         } else if(column == 1) {
396            v.x = m01;
397            v.y = m11;
398            v.z = m21;
399         }else if(column == 2){
400            v.x = m02;
401            v.y = m12;
402            v.z = m22;
403         } else {
404            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f3"));
405         }
406
407     }
408
409     /**  
410      * Copies the matrix values in the specified column into the array 
411      * parameter.
412      * @param column  the matrix column
413      * @param v    the array into which the matrix row values will be copied
414      */  
415     public final void getColumn(int column, float v[]) {
416         if( column == 0 ) {
417            v[0] = m00;
418            v[1] = m10;
419            v[2] = m20;
420         } else if(column == 1) {
421            v[0] = m01;
422            v[1] = m11;
423            v[2] = m21;
424         }else if(column == 2) {
425            v[0] = m02;
426            v[1] = m12;
427            v[2] = m22;
428         }else {
429           throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f3"));
430         }
431     }
432
433     /**
434      * Retrieves the value at the specified row and column of this
435      * matrix.
436      * @param row the row number to be retrieved (zero indexed)
437      * @param column the column number to be retrieved (zero indexed)
438      * @return the value at the indexed element.
439      */
440     public final float getElement(int row, int column)
441     {
442         switch (row) 
443           {
444           case 0:
445             switch(column)
446               {
447               case 0:
448                 return(this.m00);
449               case 1:
450                 return(this.m01);
451               case 2:
452                 return(this.m02);
453               default:
454                 break;
455               }
456             break;
457           case 1:
458             switch(column) 
459               {
460               case 0:
461                 return(this.m10);
462               case 1:
463                 return(this.m11);
464               case 2:
465                 return(this.m12);
466               default:
467                 break;
468               }
469             break;
470           
471           case 2:
472             switch(column) 
473               {
474               case 0:
475                 return(this.m20);
476               case 1:
477                 return(this.m21);
478               case 2:
479                 return(this.m22);
480               default:
481                 break;
482               }
483             break;
484             
485           default:
486             break;
487           }
488        throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f5"));
489     }
490
491     /**
492      * Sets the specified row of this matrix3f to the three values provided.
493      * @param row the row number to be modified (zero indexed)
494      * @param x the first column element
495      * @param y the second column element
496      * @param z the third column element
497      */
498     public final void setRow(int row, float x, float y, float z)
499     {
500         switch (row) {
501         case 0:
502             this.m00 = x;
503             this.m01 = y;
504             this.m02 = z;
505             break;
506
507         case 1:
508             this.m10 = x;
509             this.m11 = y;
510             this.m12 = z;
511             break;
512
513         case 2:
514             this.m20 = x;
515             this.m21 = y;
516             this.m22 = z;
517             break;
518
519         default:
520           throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
521         }
522     }
523
524     /**
525      * Sets the specified row of this matrix3f to the Vector provided.
526      * @param row the row number to be modified (zero indexed)
527      * @param v the replacement row
528      */
529     public final void setRow(int row, Vector3f v)
530     {
531         switch (row) {
532         case 0:
533             this.m00 = v.x;
534             this.m01 = v.y;
535             this.m02 = v.z;
536             break;
537
538         case 1:
539             this.m10 = v.x;
540             this.m11 = v.y;
541             this.m12 = v.z;
542             break;
543
544         case 2:
545             this.m20 = v.x;
546             this.m21 = v.y;
547             this.m22 = v.z;
548             break;
549
550         default:
551           throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
552         }
553     }
554
555     /**
556      * Sets the specified row of this matrix3f to the three values provided.
557      * @param row the row number to be modified (zero indexed)
558      * @param v the replacement row
559      */
560     public final void setRow(int row, float v[])
561     {
562         switch (row) {
563         case 0:
564             this.m00 = v[0];
565             this.m01 = v[1];
566             this.m02 = v[2];
567             break;
568
569         case 1:
570             this.m10 = v[0];
571             this.m11 = v[1];
572             this.m12 = v[2];
573             break;
574
575         case 2:
576             this.m20 = v[0];
577             this.m21 = v[1];
578             this.m22 = v[2];
579             break;
580
581         default:
582             throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f6"));
583         }
584     }
585
586     /**
587      * Sets the specified column of this matrix3f to the three values provided.
588      * @param column the column number to be modified (zero indexed)
589      * @param x the first row element
590      * @param y the second row element
591      * @param z the third row element
592      */
593     public final void setColumn(int column, float x, float y, float z)
594     {
595         switch (column) {
596         case 0:
597             this.m00 = x;
598             this.m10 = y;
599             this.m20 = z;
600             break;
601
602         case 1:
603             this.m01 = x;
604             this.m11 = y;
605             this.m21 = z;
606             break;
607
608         case 2:
609             this.m02 = x;
610             this.m12 = y;
611             this.m22 = z;
612             break;
613
614         default:
615             throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
616         }
617     }
618
619     /**
620      * Sets the specified column of this matrix3f to the vector provided.
621      * @param column the column number to be modified (zero indexed)
622      * @param v the replacement column
623      */
624     public final void setColumn(int column, Vector3f v)
625     {
626         switch (column) {
627         case 0:
628             this.m00 = v.x;
629             this.m10 = v.y;
630             this.m20 = v.z;
631             break;
632
633         case 1:
634             this.m01 = v.x;
635             this.m11 = v.y;
636             this.m21 = v.z;
637             break;
638
639         case 2:
640             this.m02 = v.x;
641             this.m12 = v.y;
642             this.m22 = v.z;
643             break;
644
645         default:
646             throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
647         }
648     }
649
650     /**
651      * Sets the specified column of this matrix3f to the three values provided.
652      * @param column the column number to be modified (zero indexed)
653      * @param v the replacement column
654      */
655     public final void setColumn(int column, float v[])
656     {
657         switch (column) {
658         case 0:
659             this.m00 = v[0];
660             this.m10 = v[1];
661             this.m20 = v[2];
662             break;
663
664         case 1:
665             this.m01 = v[0];
666             this.m11 = v[1];
667             this.m21 = v[2];
668             break;
669
670         case 2:
671             this.m02 = v[0];
672             this.m12 = v[1];
673             this.m22 = v[2];
674             break;
675
676         default:
677             throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3f9"));
678         }
679     }
680
681    /**
682      * Performs an SVD normalization of this matrix to calculate
683      * and return the uniform scale factor. If the matrix has non-uniform 
684      * scale factors, the largest of the x, y, and z scale factors will 
685      * be returned. This matrix is not modified.
686      * @return  the scale factor of this matrix
687      */  
688     public final float getScale()
689     {
690         
691         double[]    tmp_rot = new double[9];  // scratch matrix
692         double[]    tmp_scale = new double[3];  // scratch matrix
693         getScaleRotate(tmp_scale, tmp_rot);
694
695         return( (float)Matrix3d.max3(tmp_scale ));
696
697     } 
698
699    /**
700      *  Adds a scalar to each component of this matrix.
701      *  @param scalar  the scalar adder
702      */
703     public final void add(float scalar)
704     {
705         m00 += scalar;
706         m01 += scalar;
707         m02 += scalar;
708         m10 += scalar;
709         m11 += scalar;
710         m12 += scalar;
711         m20 += scalar;
712         m21 += scalar;
713         m22 += scalar;
714     }
715
716    /** 
717      *  Adds a scalar to each component of the matrix m1 and places
718      *  the result into this.  Matrix m1 is not modified.
719      *  @param scalar  the scalar adder.
720      *  @param m1  the original matrix values
721      */   
722     public final void add(float scalar, Matrix3f m1) 
723     {
724         this.m00 = m1.m00 +  scalar;
725         this.m01 = m1.m01 +  scalar;
726         this.m02 = m1.m02 +  scalar;
727         this.m10 = m1.m10 +  scalar;
728         this.m11 = m1.m11 +  scalar;
729         this.m12 = m1.m12 +  scalar;
730         this.m20 = m1.m20 +  scalar;
731         this.m21 = m1.m21 +  scalar;
732         this.m22 = m1.m22 +  scalar;
733     } 
734
735     /**
736      * Sets the value of this matrix to the matrix sum of matrices m1 and m2.
737      * @param m1 the first matrix
738      * @param m2 the second matrix
739      */
740     public final void add(Matrix3f m1, Matrix3f m2)
741     {
742         this.m00 = m1.m00 + m2.m00;
743         this.m01 = m1.m01 + m2.m01;
744         this.m02 = m1.m02 + m2.m02;
745
746         this.m10 = m1.m10 + m2.m10;
747         this.m11 = m1.m11 + m2.m11;
748         this.m12 = m1.m12 + m2.m12;
749
750         this.m20 = m1.m20 + m2.m20;
751         this.m21 = m1.m21 + m2.m21;
752         this.m22 = m1.m22 + m2.m22;
753     }
754
755     /**
756      * Sets the value of this matrix to the matrix sum of itself and 
757      * matrix m1.
758      * @param m1 the other matrix
759      */
760     public final void add(Matrix3f m1)
761     {  
762         this.m00 += m1.m00;
763         this.m01 += m1.m01;
764         this.m02 += m1.m02;
765  
766         this.m10 += m1.m10;
767         this.m11 += m1.m11;
768         this.m12 += m1.m12;
769  
770         this.m20 += m1.m20;
771         this.m21 += m1.m21;
772         this.m22 += m1.m22;
773     }  
774
775     /**
776      * Sets the value of this matrix to the matrix difference
777      * of matrices m1 and m2.
778      * @param m1 the first matrix
779      * @param m2 the second matrix
780      */
781     public final void sub(Matrix3f m1, Matrix3f m2)
782     {
783         this.m00 = m1.m00 - m2.m00;
784         this.m01 = m1.m01 - m2.m01;
785         this.m02 = m1.m02 - m2.m02;
786
787         this.m10 = m1.m10 - m2.m10;
788         this.m11 = m1.m11 - m2.m11;
789         this.m12 = m1.m12 - m2.m12;
790
791         this.m20 = m1.m20 - m2.m20;
792         this.m21 = m1.m21 - m2.m21;
793         this.m22 = m1.m22 - m2.m22;
794     }
795
796     /**  
797      * Sets the value of this matrix to the matrix difference
798      * of itself and matrix m1 (this = this - m1).
799      * @param m1 the other matrix
800      */  
801     public final void sub(Matrix3f m1)
802     {  
803         this.m00 -= m1.m00;
804         this.m01 -= m1.m01;
805         this.m02 -= m1.m02;
806  
807         this.m10 -= m1.m10;
808         this.m11 -= m1.m11;
809         this.m12 -= m1.m12;
810  
811         this.m20 -= m1.m20;
812         this.m21 -= m1.m21;
813         this.m22 -= m1.m22;
814     }
815
816     /**
817      * Sets the value of this matrix to its transpose.
818      */
819     public final void transpose()
820     {
821         float temp;
822
823         temp = this.m10;
824         this.m10 = this.m01;
825         this.m01 = temp;
826
827         temp = this.m20;
828         this.m20 = this.m02;
829         this.m02 = temp;
830
831         temp = this.m21;
832         this.m21 = this.m12;
833         this.m12 = temp;
834     }
835
836     /**
837      * Sets the value of this matrix to the transpose of the argument matrix.
838      * @param m1 the matrix to be transposed
839      */
840     public final void transpose(Matrix3f m1)
841     {
842         if (this != m1) {
843             this.m00 = m1.m00;
844             this.m01 = m1.m10;
845             this.m02 = m1.m20;
846
847             this.m10 = m1.m01;
848             this.m11 = m1.m11;
849             this.m12 = m1.m21;
850
851             this.m20 = m1.m02;
852             this.m21 = m1.m12;
853             this.m22 = m1.m22;
854         } else
855             this.transpose();
856     }
857
858     /**
859      * Sets the value of this matrix to the matrix conversion of the
860      * (single precision) quaternion argument.
861      * @param q1 the quaternion to be converted
862      */
863     public final void set(Quat4f q1)
864     {
865         this.m00 = 1.0f - 2.0f*q1.y*q1.y - 2.0f*q1.z*q1.z;
866         this.m10 = 2.0f*(q1.x*q1.y + q1.w*q1.z);
867         this.m20 = 2.0f*(q1.x*q1.z - q1.w*q1.y);
868
869         this.m01 = 2.0f*(q1.x*q1.y - q1.w*q1.z);
870         this.m11 = 1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.z*q1.z;
871         this.m21 = 2.0f*(q1.y*q1.z + q1.w*q1.x);
872
873         this.m02 = 2.0f*(q1.x*q1.z + q1.w*q1.y);
874         this.m12 = 2.0f*(q1.y*q1.z - q1.w*q1.x);
875         this.m22 = 1.0f - 2.0f*q1.x*q1.x - 2.0f*q1.y*q1.y;
876     }
877
878     /**
879      * Sets the value of this matrix to the matrix conversion of the
880      * (single precision) axis and angle argument.
881      * @param a1 the axis and angle to be converted
882      */
883     public final void set(AxisAngle4f a1)
884     {
885       float mag = (float)Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
886       if( mag < EPS ) {
887          m00 = 1.0f;
888          m01 = 0.0f;
889          m02 = 0.0f;
890
891          m10 = 0.0f;
892          m11 = 1.0f;
893          m12 = 0.0f;
894
895          m20 = 0.0f;
896          m21 = 0.0f;
897          m22 = 1.0f;
898       } else {
899          mag = 1.0f/mag;
900          float ax = a1.x*mag;
901          float ay = a1.y*mag;
902          float az = a1.z*mag;
903
904          float sinTheta = (float)Math.sin((float)a1.angle);
905          float cosTheta = (float)Math.cos((float)a1.angle);
906          float t = (float)1.0 - cosTheta;
907
908          float xz = ax * az;    
909          float xy = ax * ay;
910          float yz = ay * az;
911
912          m00 = t * ax * ax + cosTheta;
913          m01 = t * xy - sinTheta * az;
914          m02 = t * xz + sinTheta * ay;
915     
916          m10 = t * xy + sinTheta * az;
917          m11 = t * ay * ay + cosTheta;
918          m12 = t * yz - sinTheta * ax;
919     
920          m20 = t * xz - sinTheta * ay;
921          m21 = t * yz + sinTheta * ax;
922          m22 = t * az * az + cosTheta;
923       }
924
925     }
926
927     /**
928      * Sets the value of this matrix to the matrix conversion of the
929      * (double precision) axis and angle argument.
930      * @param a1 the axis and angle to be converted
931      */
932     public final void set(AxisAngle4d a1)
933     {
934       double mag = Math.sqrt( a1.x*a1.x + a1.y*a1.y + a1.z*a1.z);
935       if( mag < EPS ) {
936          m00 = 1.0f;
937          m01 = 0.0f;
938          m02 = 0.0f;
939
940          m10 = 0.0f;
941          m11 = 1.0f;
942          m12 = 0.0f;
943
944          m20 = 0.0f;
945          m21 = 0.0f;
946          m22 = 1.0f;
947       } else {
948          mag = 1.0/mag;
949          double ax = a1.x*mag;
950          double ay = a1.y*mag;
951          double az = a1.z*mag;
952
953          double sinTheta = Math.sin(a1.angle);
954          double cosTheta = Math.cos(a1.angle);
955          double t = 1.0 - cosTheta;
956
957          double xz = ax * az;    
958          double xy = ax * ay;
959          double yz = ay * az;
960
961          m00 = (float)(t * ax * ax + cosTheta);
962          m01 = (float)(t * xy - sinTheta * az);
963          m02 = (float)(t * xz + sinTheta * ay);
964     
965          m10 = (float)(t * xy + sinTheta * az);
966          m11 = (float)(t * ay * ay + cosTheta);
967          m12 = (float)(t * yz - sinTheta * ax);
968     
969          m20 = (float)(t * xz - sinTheta * ay);
970          m21 = (float)(t * yz + sinTheta * ax);
971          m22 = (float)(t * az * az + cosTheta);
972       }
973
974     }
975
976     /**
977      * Sets the value of this matrix to the matrix conversion of the
978      * (single precision) quaternion argument.
979      * @param q1 the quaternion to be converted
980      */
981     public final void set(Quat4d q1)
982     {
983         this.m00 = (float) (1.0 - 2.0*q1.y*q1.y - 2.0*q1.z*q1.z);
984         this.m10 = (float) (2.0*(q1.x*q1.y + q1.w*q1.z));
985         this.m20 = (float) (2.0*(q1.x*q1.z - q1.w*q1.y));
986
987         this.m01 = (float) (2.0*(q1.x*q1.y - q1.w*q1.z));
988         this.m11 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.z*q1.z);
989         this.m21 = (float) (2.0*(q1.y*q1.z + q1.w*q1.x));
990
991         this.m02 = (float) (2.0*(q1.x*q1.z + q1.w*q1.y));
992         this.m12 = (float) (2.0*(q1.y*q1.z - q1.w*q1.x));
993         this.m22 = (float) (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y);
994     }
995
996     /** 
997      *  Sets the values in this Matrix3f equal to the row-major 
998      *  array parameter (ie, the first three elements of the 
999      *  array will be copied into the first row of this matrix, etc.). 
1000      *  @param m  the single precision array of length 9 
1001      */   
1002     public final void set(float[] m) 
1003     {
1004        m00 = m[0];
1005        m01 = m[1];
1006        m02 = m[2];
1007  
1008        m10 = m[3];
1009        m11 = m[4];
1010        m12 = m[5];
1011  
1012        m20 = m[6];
1013        m21 = m[7];
1014        m22 = m[8];
1015
1016         
1017     } 
1018
1019     /**
1020      * Sets the value of this matrix to the value of the Matrix3f 
1021      * argument. 
1022      * @param m1 the source matrix3f 
1023      */  
1024     public final void set(Matrix3f m1) {
1025
1026         this.m00 = m1.m00;
1027         this.m01 = m1.m01;
1028         this.m02 = m1.m02;
1029
1030         this.m10 = m1.m10;
1031         this.m11 = m1.m11;
1032         this.m12 = m1.m12;
1033
1034         this.m20 = m1.m20;
1035         this.m21 = m1.m21;
1036         this.m22 = m1.m22;
1037
1038     }
1039
1040  
1041     /**
1042      * Sets the value of this matrix to the float value of the Matrix3d 
1043      * argument. 
1044      * @param m1 the source matrix3d 
1045      */  
1046     public final void set(Matrix3d m1) { 
1047  
1048         this.m00 = (float)m1.m00; 
1049         this.m01 = (float)m1.m01; 
1050         this.m02 = (float)m1.m02; 
1051  
1052         this.m10 = (float)m1.m10; 
1053         this.m11 = (float)m1.m11;
1054         this.m12 = (float)m1.m12;
1055  
1056         this.m20 = (float)m1.m20;
1057         this.m21 = (float)m1.m21; 
1058         this.m22 = (float)m1.m22;
1059  
1060     }
1061  
1062
1063     /**
1064      * Sets the value of this matrix to the matrix inverse
1065      * of the passed matrix m1.
1066      * @param m1 the matrix to be inverted
1067      */
1068     public final void invert(Matrix3f m1)
1069     {
1070          invertGeneral( m1);
1071     }
1072
1073     /**
1074      * Inverts this matrix in place.
1075      */
1076     public final void invert()
1077     {
1078         invertGeneral( this );
1079     }
1080
1081     /**
1082      * General invert routine.  Inverts m1 and places the result in "this".
1083      * Note that this routine handles both the "this" version and the
1084      * non-"this" version.
1085      *
1086      * Also note that since this routine is slow anyway, we won't worry
1087      * about allocating a little bit of garbage.
1088      */
1089     private final void invertGeneral(Matrix3f  m1) {
1090         double temp[] = new double[9];
1091         double result[] = new double[9];
1092         int row_perm[] = new int[3];
1093         int i, r, c;
1094
1095         // Use LU decomposition and backsubstitution code specifically
1096         // for floating-point 3x3 matrices.
1097
1098         // Copy source matrix to t1tmp 
1099         temp[0] = (double)m1.m00;
1100         temp[1] = (double)m1.m01;
1101         temp[2] = (double)m1.m02;
1102  
1103         temp[3] = (double)m1.m10;
1104         temp[4] = (double)m1.m11;
1105         temp[5] = (double)m1.m12;
1106  
1107         temp[6] = (double)m1.m20;
1108         temp[7] = (double)m1.m21;
1109         temp[8] = (double)m1.m22;
1110  
1111
1112         // Calculate LU decomposition: Is the matrix singular? 
1113         if (!luDecomposition(temp, row_perm)) {
1114             // Matrix has no inverse 
1115             throw new SingularMatrixException(VecMathI18N.getString("Matrix3f12"));
1116         }
1117
1118         // Perform back substitution on the identity matrix 
1119         for(i=0;i<9;i++) result[i] = 0.0;
1120         result[0] = 1.0; result[4] = 1.0; result[8] = 1.0;
1121         luBacksubstitution(temp, row_perm, result);
1122
1123         this.m00 = (float)result[0];
1124         this.m01 = (float)result[1];
1125         this.m02 = (float)result[2];
1126
1127         this.m10 = (float)result[3];
1128         this.m11 = (float)result[4];
1129         this.m12 = (float)result[5];
1130  
1131         this.m20 = (float)result[6];
1132         this.m21 = (float)result[7];
1133         this.m22 = (float)result[8];
1134
1135     }
1136
1137     /**
1138      * Given a 3x3 array "matrix0", this function replaces it with the 
1139      * LU decomposition of a row-wise permutation of itself.  The input 
1140      * parameters are "matrix0" and "dimen".  The array "matrix0" is also 
1141      * an output parameter.  The vector "row_perm[3]" is an output 
1142      * parameter that contains the row permutations resulting from partial 
1143      * pivoting.  The output parameter "even_row_xchg" is 1 when the 
1144      * number of row exchanges is even, or -1 otherwise.  Assumes data 
1145      * type is always double.
1146      *
1147      * This function is similar to luDecomposition, except that it
1148      * is tuned specifically for 3x3 matrices.
1149      *
1150      * @return true if the matrix is nonsingular, or false otherwise.
1151      */
1152     //
1153     // Reference: Press, Flannery, Teukolsky, Vetterling, 
1154     //        _Numerical_Recipes_in_C_, Cambridge University Press, 
1155     //        1988, pp 40-45.
1156     //
1157     static boolean luDecomposition(double[] matrix0,
1158                                    int[] row_perm) {
1159
1160         double row_scale[] = new double[3];
1161
1162         // Determine implicit scaling information by looping over rows 
1163         {
1164             int i, j;
1165             int ptr, rs;
1166             double big, temp;
1167
1168             ptr = 0;
1169             rs = 0;
1170
1171             // For each row ... 
1172             i = 3;
1173             while (i-- != 0) {
1174                 big = 0.0;
1175
1176                 // For each column, find the largest element in the row 
1177                 j = 3;
1178                 while (j-- != 0) {
1179                     temp = matrix0[ptr++];
1180                     temp = Math.abs(temp);
1181                     if (temp > big) {
1182                         big = temp;
1183                     }
1184                 }
1185
1186                 // Is the matrix singular? 
1187                 if (big == 0.0) {
1188                     return false;
1189                 }
1190                 row_scale[rs++] = 1.0 / big;
1191             }
1192         }
1193
1194         {
1195             int j;
1196             int mtx;
1197
1198             mtx = 0;
1199
1200             // For all columns, execute Crout's method 
1201             for (j = 0; j < 3; j++) {
1202                 int i, imax, k;
1203                 int target, p1, p2;
1204                 double sum, big, temp;
1205
1206                 // Determine elements of upper diagonal matrix U 
1207                 for (i = 0; i < j; i++) {
1208                     target = mtx + (3*i) + j;
1209                     sum = matrix0[target];
1210                     k = i;
1211                     p1 = mtx + (3*i);
1212                     p2 = mtx + j;
1213                     while (k-- != 0) {
1214                         sum -= matrix0[p1] * matrix0[p2];
1215                         p1++;
1216                         p2 += 3;
1217                     }
1218                     matrix0[target] = sum;
1219                 }
1220
1221                 // Search for largest pivot element and calculate
1222                 // intermediate elements of lower diagonal matrix L.
1223                 big = 0.0;
1224                 imax = -1;
1225                 for (i = j; i < 3; i++) {
1226                     target = mtx + (3*i) + j;
1227                     sum = matrix0[target];
1228                     k = j;
1229                     p1 = mtx + (3*i);
1230                     p2 = mtx + j;
1231                     while (k-- != 0) {
1232                         sum -= matrix0[p1] * matrix0[p2];
1233                         p1++;
1234                         p2 += 3;
1235                     }
1236                     matrix0[target] = sum;
1237
1238                     // Is this the best pivot so far? 
1239                     if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
1240                         big = temp;
1241                         imax = i;
1242                     }
1243                 }
1244
1245                 if (imax < 0) {
1246                     throw new RuntimeException(VecMathI18N.getString("Matrix3f13"));
1247                 }
1248
1249                 // Is a row exchange necessary? 
1250                 if (j != imax) {
1251                     // Yes: exchange rows 
1252                     k = 3;
1253                     p1 = mtx + (3*imax);
1254                     p2 = mtx + (3*j);
1255                     while (k-- != 0) {
1256                         temp = matrix0[p1];
1257                         matrix0[p1++] = matrix0[p2];
1258                         matrix0[p2++] = temp;
1259                     }
1260
1261                     // Record change in scale factor 
1262                     row_scale[imax] = row_scale[j];
1263                 }
1264
1265                 // Record row permutation 
1266                 row_perm[j] = imax;
1267
1268                 // Is the matrix singular 
1269                 if (matrix0[(mtx + (3*j) + j)] == 0.0) {
1270                     return false;
1271                 }
1272
1273                 // Divide elements of lower diagonal matrix L by pivot 
1274                 if (j != (3-1)) {
1275                     temp = 1.0 / (matrix0[(mtx + (3*j) + j)]);
1276                     target = mtx + (3*(j+1)) + j;
1277                     i = 2 - j;
1278                     while (i-- != 0) {
1279                         matrix0[target] *= temp;
1280                         target += 3;
1281                     }
1282                 }
1283             }
1284         }
1285
1286         return true;
1287     }
1288
1289     /**
1290      * Solves a set of linear equations.  The input parameters "matrix1",
1291      * and "row_perm" come from luDecompostionD3x3 and do not change
1292      * here.  The parameter "matrix2" is a set of column vectors assembled
1293      * into a 3x3 matrix of floating-point values.  The procedure takes each
1294      * column of "matrix2" in turn and treats it as the right-hand side of the
1295      * matrix equation Ax = LUx = b.  The solution vector replaces the
1296      * original column of the matrix.
1297      *
1298      * If "matrix2" is the identity matrix, the procedure replaces its contents
1299      * with the inverse of the matrix from which "matrix1" was originally
1300      * derived.
1301      */
1302     //
1303     // Reference: Press, Flannery, Teukolsky, Vetterling, 
1304     //        _Numerical_Recipes_in_C_, Cambridge University Press, 
1305     //        1988, pp 44-45.
1306     //
1307     static void luBacksubstitution(double[] matrix1,
1308                                    int[] row_perm,
1309                                    double[] matrix2) {
1310
1311         int i, ii, ip, j, k;
1312         int rp;
1313         int cv, rv;
1314         
1315         //      rp = row_perm;
1316         rp = 0;
1317
1318         // For each column vector of matrix2 ... 
1319         for (k = 0; k < 3; k++) {
1320             //      cv = &(matrix2[0][k]);
1321             cv = k;
1322             ii = -1;
1323
1324             // Forward substitution 
1325             for (i = 0; i < 3; i++) {
1326                 double sum;
1327
1328                 ip = row_perm[rp+i];
1329                 sum = matrix2[cv+3*ip];
1330                 matrix2[cv+3*ip] = matrix2[cv+3*i];
1331                 if (ii >= 0) {
1332                     //              rv = &(matrix1[i][0]);
1333                     rv = i*3;
1334                     for (j = ii; j <= i-1; j++) {
1335                         sum -= matrix1[rv+j] * matrix2[cv+3*j];
1336                     }
1337                 }
1338                 else if (sum != 0.0) {
1339                     ii = i;
1340                 }
1341                 matrix2[cv+3*i] = sum;
1342             }
1343
1344             // Backsubstitution 
1345             //      rv = &(matrix1[3][0]);
1346             rv = 2*3;
1347             matrix2[cv+3*2] /= matrix1[rv+2];
1348
1349             rv -= 3;
1350             matrix2[cv+3*1] = (matrix2[cv+3*1] -
1351                             matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+1];
1352
1353             rv -= 3;
1354             matrix2[cv+4*0] = (matrix2[cv+3*0] -
1355                             matrix1[rv+1] * matrix2[cv+3*1] -
1356                             matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+0];
1357
1358         }
1359     }
1360    /**
1361      * Computes the determinant of this matrix.
1362      * @return the determinant of this matrix
1363      */
1364     public final float determinant()
1365     {
1366        float total;
1367        total =  this.m00*(this.m11*this.m22 - this.m12*this.m21)
1368               + this.m01*(this.m12*this.m20 - this.m10*this.m22)
1369               + this.m02*(this.m10*this.m21 - this.m11*this.m20); 
1370        return total;
1371     }
1372
1373     /**
1374      * Sets the value of this matrix to a scale matrix with
1375      * the passed scale amount.
1376      * @param scale the scale factor for the matrix
1377      */
1378     public final void set(float scale)
1379     {
1380         this.m00 = scale;
1381         this.m01 = (float) 0.0;
1382         this.m02 = (float) 0.0;
1383
1384         this.m10 = (float) 0.0;
1385         this.m11 = scale;
1386         this.m12 = (float) 0.0;
1387
1388         this.m20 = (float) 0.0;
1389         this.m21 = (float) 0.0;
1390         this.m22 = scale;
1391     }
1392
1393     /**
1394      * Sets the value of this matrix to a counter clockwise rotation 
1395      * about the x axis.
1396      * @param angle the angle to rotate about the X axis in radians
1397      */
1398     public final void rotX(float angle)
1399     {
1400         float   sinAngle, cosAngle;
1401
1402         sinAngle = (float) Math.sin((double) angle);
1403         cosAngle = (float) Math.cos((double) angle);
1404
1405         this.m00 = (float) 1.0;
1406         this.m01 = (float) 0.0;
1407         this.m02 = (float) 0.0;
1408
1409         this.m10 = (float) 0.0;
1410         this.m11 = cosAngle;
1411         this.m12 = -sinAngle;
1412
1413         this.m20 = (float) 0.0;
1414         this.m21 = sinAngle;
1415         this.m22 = cosAngle;
1416     }
1417
1418     /**
1419      * Sets the value of this matrix to a counter clockwise rotation 
1420      * about the y axis.
1421      * @param angle the angle to rotate about the Y axis in radians
1422      */
1423     public final void rotY(float angle)
1424     {
1425         float   sinAngle, cosAngle;
1426
1427         sinAngle = (float) Math.sin((double) angle);
1428         cosAngle = (float) Math.cos((double) angle);
1429
1430         this.m00 = cosAngle;
1431         this.m01 = (float) 0.0;
1432         this.m02 = sinAngle;
1433
1434         this.m10 = (float) 0.0;
1435         this.m11 = (float) 1.0;
1436         this.m12 = (float) 0.0;
1437
1438         this.m20 = -sinAngle;
1439         this.m21 = (float) 0.0;
1440         this.m22 = cosAngle;
1441     }
1442
1443     /**
1444      * Sets the value of this matrix to a counter clockwise rotation 
1445      * about the z axis.
1446      * @param angle the angle to rotate about the Z axis in radians
1447      */
1448     public final void rotZ(float angle)
1449     {
1450         float   sinAngle, cosAngle;
1451
1452         sinAngle = (float) Math.sin((double) angle);
1453         cosAngle = (float) Math.cos((double) angle);
1454
1455         this.m00 = cosAngle;
1456         this.m01 = -sinAngle;
1457         this.m02 = (float) 0.0;
1458
1459         this.m10 = sinAngle;
1460         this.m11 = cosAngle;
1461         this.m12 = (float) 0.0;
1462
1463         this.m20 = (float) 0.0;
1464         this.m21 = (float) 0.0;
1465         this.m22 = (float) 1.0;
1466     }
1467
1468    /**
1469      * Multiplies each element of this matrix by a scalar.
1470      * @param scalar  the scalar multiplier
1471      */
1472     public final void mul(float scalar)
1473     {
1474        m00 *= scalar;
1475        m01 *= scalar;
1476        m02 *= scalar;
1477
1478        m10 *= scalar;
1479        m11 *= scalar;
1480        m12 *= scalar;
1481
1482        m20 *= scalar;
1483        m21 *= scalar;
1484        m22 *= scalar;
1485     }
1486
1487    /**   
1488      * Multiplies each element of matrix m1 by a scalar and places
1489      * the result into this.  Matrix m1 is not modified.
1490      * @param scalar  the scalar multiplier
1491      * @param m1  the original matrix
1492      */   
1493     public final void mul(float scalar, Matrix3f m1)
1494     { 
1495         this.m00 = scalar * m1.m00;
1496         this.m01 = scalar * m1.m01;
1497         this.m02 = scalar * m1.m02;
1498  
1499         this.m10 = scalar * m1.m10;
1500         this.m11 = scalar * m1.m11;
1501         this.m12 = scalar * m1.m12;
1502  
1503         this.m20 = scalar * m1.m20;
1504         this.m21 = scalar * m1.m21;
1505         this.m22 = scalar * m1.m22;
1506
1507     } 
1508
1509    /**
1510      * Sets the value of this matrix to the result of multiplying itself
1511      * with matrix m1.
1512      * @param m1 the other matrix
1513      */  
1514     public final void mul(Matrix3f m1)
1515     {
1516           float       m00, m01, m02,
1517                       m10, m11, m12,
1518                       m20, m21, m22;
1519
1520             m00 = this.m00*m1.m00 + this.m01*m1.m10 + this.m02*m1.m20;
1521             m01 = this.m00*m1.m01 + this.m01*m1.m11 + this.m02*m1.m21;
1522             m02 = this.m00*m1.m02 + this.m01*m1.m12 + this.m02*m1.m22;
1523  
1524             m10 = this.m10*m1.m00 + this.m11*m1.m10 + this.m12*m1.m20;
1525             m11 = this.m10*m1.m01 + this.m11*m1.m11 + this.m12*m1.m21;
1526             m12 = this.m10*m1.m02 + this.m11*m1.m12 + this.m12*m1.m22;
1527  
1528             m20 = this.m20*m1.m00 + this.m21*m1.m10 + this.m22*m1.m20;
1529             m21 = this.m20*m1.m01 + this.m21*m1.m11 + this.m22*m1.m21;
1530             m22 = this.m20*m1.m02 + this.m21*m1.m12 + this.m22*m1.m22;
1531  
1532             this.m00 = m00; this.m01 = m01; this.m02 = m02;
1533             this.m10 = m10; this.m11 = m11; this.m12 = m12;
1534             this.m20 = m20; this.m21 = m21; this.m22 = m22;
1535     }
1536
1537     /**
1538      * Sets the value of this matrix to the result of multiplying
1539      * the two argument matrices together.
1540      * @param m1 the first matrix
1541      * @param m2 the second matrix
1542      */
1543     public final void mul(Matrix3f m1, Matrix3f m2)
1544     {
1545         if (this != m1 && this != m2) {
1546             this.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
1547             this.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
1548             this.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
1549
1550             this.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
1551             this.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
1552             this.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
1553
1554             this.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
1555             this.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
1556             this.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
1557         } else {
1558             float       m00, m01, m02,
1559                         m10, m11, m12,
1560                         m20, m21, m22;
1561
1562             m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20; 
1563             m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21; 
1564             m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22; 
1565  
1566             m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20; 
1567             m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21; 
1568             m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22; 
1569  
1570             m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20; 
1571             m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21; 
1572             m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22; 
1573
1574             this.m00 = m00; this.m01 = m01; this.m02 = m02;
1575             this.m10 = m10; this.m11 = m11; this.m12 = m12;
1576             this.m20 = m20; this.m21 = m21; this.m22 = m22;
1577         }
1578     }
1579
1580    /**
1581      *  Multiplies this matrix by matrix m1, does an SVD normalization 
1582      *  of the result, and places the result back into this matrix.
1583      *  this = SVDnorm(this*m1).
1584      *  @param  m1 the matrix on the right hand side of the multiplication
1585      */
1586     public final void mulNormalize(Matrix3f m1){
1587         
1588         double[]    tmp = new double[9];  // scratch matrix
1589         double[]    tmp_rot = new double[9];  // scratch matrix
1590         double[]    tmp_scale = new double[3];  // scratch matrix
1591
1592         tmp[0] = this.m00*m1.m00 + this.m01*m1.m10 + this.m02*m1.m20;
1593         tmp[1] = this.m00*m1.m01 + this.m01*m1.m11 + this.m02*m1.m21;
1594         tmp[2] = this.m00*m1.m02 + this.m01*m1.m12 + this.m02*m1.m22;
1595
1596         tmp[3] = this.m10*m1.m00 + this.m11*m1.m10 + this.m12*m1.m20;
1597         tmp[4] = this.m10*m1.m01 + this.m11*m1.m11 + this.m12*m1.m21;
1598         tmp[5] = this.m10*m1.m02 + this.m11*m1.m12 + this.m12*m1.m22;
1599
1600         tmp[6] = this.m20*m1.m00 + this.m21*m1.m10 + this.m22*m1.m20;
1601         tmp[7] = this.m20*m1.m01 + this.m21*m1.m11 + this.m22*m1.m21;
1602         tmp[8] = this.m20*m1.m02 + this.m21*m1.m12 + this.m22*m1.m22;
1603
1604         Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot);
1605
1606         this.m00 = (float)(tmp_rot[0]);
1607         this.m01 = (float)(tmp_rot[1]);
1608         this.m02 = (float)(tmp_rot[2]);
1609
1610         this.m10 = (float)(tmp_rot[3]);
1611         this.m11 = (float)(tmp_rot[4]);
1612         this.m12 = (float)(tmp_rot[5]);
1613
1614         this.m20 = (float)(tmp_rot[6]);
1615         this.m21 = (float)(tmp_rot[7]);
1616         this.m22 = (float)(tmp_rot[8]);
1617
1618     }
1619
1620    /**
1621      *  Multiplies matrix m1 by matrix m2, does an SVD normalization 
1622      *  of the result, and places the result into this matrix.
1623      *  this = SVDnorm(m1*m2).
1624      *  @param m1  the matrix on the left hand side of the multiplication
1625      *  @param m2  the matrix on the right hand side of the multiplication
1626      */  
1627     public final void mulNormalize(Matrix3f m1, Matrix3f m2){
1628         
1629         double[]    tmp = new double[9];  // scratch matrix
1630         double[]    tmp_rot = new double[9];  // scratch matrix
1631         double[]    tmp_scale = new double[3];  // scratch matrix
1632
1633         
1634         tmp[0] = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
1635         tmp[1] = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
1636         tmp[2] = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
1637  
1638         tmp[3] = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
1639         tmp[4] = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21; 
1640         tmp[5] = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22; 
1641  
1642         tmp[6] = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
1643         tmp[7] = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21; 
1644         tmp[8] = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22; 
1645  
1646         Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot);
1647  
1648         this.m00 = (float)(tmp_rot[0]);
1649         this.m01 = (float)(tmp_rot[1]);
1650         this.m02 = (float)(tmp_rot[2]);
1651  
1652         this.m10 = (float)(tmp_rot[3]);
1653         this.m11 = (float)(tmp_rot[4]);
1654         this.m12 = (float)(tmp_rot[5]);
1655  
1656         this.m20 = (float)(tmp_rot[6]);
1657         this.m21 = (float)(tmp_rot[7]);
1658         this.m22 = (float)(tmp_rot[8]);
1659     }
1660
1661    /**
1662      *  Multiplies the transpose of matrix m1 times the transpose of matrix
1663      *  m2, and places the result into this.
1664      *  @param m1  the matrix on the left hand side of the multiplication
1665      *  @param m2  the matrix on the right hand side of the multiplication
1666      */
1667     public final void mulTransposeBoth(Matrix3f m1, Matrix3f m2)
1668     {
1669         if (this != m1 && this != m2) {
1670             this.m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02;
1671             this.m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12;
1672             this.m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22;
1673
1674             this.m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02;
1675             this.m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12;
1676             this.m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22;
1677
1678             this.m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02;
1679             this.m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12;
1680             this.m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22;
1681         } else {
1682             float       m00, m01, m02,
1683                         m10, m11, m12,
1684                 m20, m21, m22;  // vars for temp result matrix 
1685
1686             m00 = m1.m00*m2.m00 + m1.m10*m2.m01 + m1.m20*m2.m02;
1687             m01 = m1.m00*m2.m10 + m1.m10*m2.m11 + m1.m20*m2.m12;
1688             m02 = m1.m00*m2.m20 + m1.m10*m2.m21 + m1.m20*m2.m22;
1689
1690             m10 = m1.m01*m2.m00 + m1.m11*m2.m01 + m1.m21*m2.m02;
1691             m11 = m1.m01*m2.m10 + m1.m11*m2.m11 + m1.m21*m2.m12;
1692             m12 = m1.m01*m2.m20 + m1.m11*m2.m21 + m1.m21*m2.m22;
1693
1694             m20 = m1.m02*m2.m00 + m1.m12*m2.m01 + m1.m22*m2.m02;
1695             m21 = m1.m02*m2.m10 + m1.m12*m2.m11 + m1.m22*m2.m12;
1696             m22 = m1.m02*m2.m20 + m1.m12*m2.m21 + m1.m22*m2.m22;
1697
1698             this.m00 = m00; this.m01 = m01; this.m02 = m02;
1699             this.m10 = m10; this.m11 = m11; this.m12 = m12;
1700             this.m20 = m20; this.m21 = m21; this.m22 = m22;
1701         }
1702
1703     }
1704  
1705
1706    /**   
1707      *  Multiplies matrix m1 times the transpose of matrix m2, and
1708      *  places the result into this.
1709      *  @param m1  the matrix on the left hand side of the multiplication 
1710      *  @param m2  the matrix on the right hand side of the multiplication
1711      */  
1712     public final void mulTransposeRight(Matrix3f m1, Matrix3f m2) 
1713   { 
1714     if (this != m1 && this != m2) {
1715       this.m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02;
1716       this.m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12;
1717       this.m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22;
1718         
1719       this.m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02;
1720       this.m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12;
1721       this.m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22;
1722         
1723       this.m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02;
1724       this.m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12;
1725       this.m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22;
1726     } else {
1727       float     m00, m01, m02,
1728         m10, m11, m12,
1729           m20, m21, m22;  // vars for temp result matrix 
1730
1731       m00 = m1.m00*m2.m00 + m1.m01*m2.m01 + m1.m02*m2.m02;
1732       m01 = m1.m00*m2.m10 + m1.m01*m2.m11 + m1.m02*m2.m12;
1733       m02 = m1.m00*m2.m20 + m1.m01*m2.m21 + m1.m02*m2.m22;
1734
1735       m10 = m1.m10*m2.m00 + m1.m11*m2.m01 + m1.m12*m2.m02; 
1736       m11 = m1.m10*m2.m10 + m1.m11*m2.m11 + m1.m12*m2.m12;
1737       m12 = m1.m10*m2.m20 + m1.m11*m2.m21 + m1.m12*m2.m22;
1738
1739       m20 = m1.m20*m2.m00 + m1.m21*m2.m01 + m1.m22*m2.m02; 
1740       m21 = m1.m20*m2.m10 + m1.m21*m2.m11 + m1.m22*m2.m12;
1741       m22 = m1.m20*m2.m20 + m1.m21*m2.m21 + m1.m22*m2.m22;
1742  
1743       this.m00 = m00; this.m01 = m01; this.m02 = m02;
1744       this.m10 = m10; this.m11 = m11; this.m12 = m12;
1745       this.m20 = m20; this.m21 = m21; this.m22 = m22;
1746     }
1747   } 
1748
1749    /**   
1750      *  Multiplies the transpose of matrix m1 times matrix m2, and 
1751      *  places the result into this.  
1752      *  @param m1  the matrix on the left hand side of the multiplication  
1753      *  @param m2  the matrix on the right hand side of the multiplication 
1754      */   
1755     public final void mulTransposeLeft(Matrix3f m1, Matrix3f m2)  
1756     {    
1757       if (this != m1 && this != m2) {
1758         this.m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20;
1759         this.m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21;
1760         this.m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22;
1761  
1762         this.m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20;
1763         this.m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21;
1764         this.m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22;
1765  
1766         this.m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20;
1767         this.m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21;
1768         this.m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22;
1769       } else {
1770         float   m00, m01, m02,
1771           m10, m11, m12,
1772             m20, m21, m22;  // vars for temp result matrix 
1773
1774         m00 = m1.m00*m2.m00 + m1.m10*m2.m10 + m1.m20*m2.m20;
1775         m01 = m1.m00*m2.m01 + m1.m10*m2.m11 + m1.m20*m2.m21;
1776         m02 = m1.m00*m2.m02 + m1.m10*m2.m12 + m1.m20*m2.m22;
1777
1778         m10 = m1.m01*m2.m00 + m1.m11*m2.m10 + m1.m21*m2.m20; 
1779         m11 = m1.m01*m2.m01 + m1.m11*m2.m11 + m1.m21*m2.m21;
1780         m12 = m1.m01*m2.m02 + m1.m11*m2.m12 + m1.m21*m2.m22;
1781
1782         m20 = m1.m02*m2.m00 + m1.m12*m2.m10 + m1.m22*m2.m20; 
1783         m21 = m1.m02*m2.m01 + m1.m12*m2.m11 + m1.m22*m2.m21;
1784         m22 = m1.m02*m2.m02 + m1.m12*m2.m12 + m1.m22*m2.m22;
1785  
1786         this.m00 = m00; this.m01 = m01; this.m02 = m02;
1787         this.m10 = m10; this.m11 = m11; this.m12 = m12;
1788         this.m20 = m20; this.m21 = m21; this.m22 = m22;
1789       }  
1790     }
1791
1792    /**
1793      * Performs singular value decomposition normalization of this matrix.   
1794      */
1795     public final void normalize(){
1796         
1797         double[]    tmp_rot = new double[9];  // scratch matrix
1798         double[]    tmp_scale = new double[3];  // scratch matrix
1799         getScaleRotate( tmp_scale, tmp_rot );
1800
1801         this.m00 = (float)tmp_rot[0];
1802         this.m01 = (float)tmp_rot[1];
1803         this.m02 = (float)tmp_rot[2];
1804
1805         this.m10 = (float)tmp_rot[3];
1806         this.m11 = (float)tmp_rot[4];
1807         this.m12 = (float)tmp_rot[5];
1808
1809         this.m20 = (float)tmp_rot[6];
1810         this.m21 = (float)tmp_rot[7];
1811         this.m22 = (float)tmp_rot[8];
1812
1813     }
1814
1815    /**   
1816      * Perform singular value decomposition normalization of matrix m1 
1817      * and place the normalized values into this.   
1818      * @param m1  the matrix values to be normalized
1819      */ 
1820     public final void normalize(Matrix3f m1){
1821         double[]    tmp = new double[9];  // scratch matrix
1822         double[]    tmp_rot = new double[9];  // scratch matrix
1823         double[]    tmp_scale = new double[3];  // scratch matrix
1824
1825         tmp[0] = m1.m00;
1826         tmp[1] = m1.m01;
1827         tmp[2] = m1.m02;
1828  
1829         tmp[3] = m1.m10;
1830         tmp[4] = m1.m11;
1831         tmp[5] = m1.m12;
1832  
1833         tmp[6] = m1.m20;
1834         tmp[7] = m1.m21;
1835         tmp[8] = m1.m22;
1836  
1837         Matrix3d.compute_svd( tmp, tmp_scale, tmp_rot );
1838  
1839         this.m00 = (float)(tmp_rot[0]);
1840         this.m01 = (float)(tmp_rot[1]);
1841         this.m02 = (float)(tmp_rot[2]);
1842  
1843         this.m10 = (float)(tmp_rot[3]);
1844         this.m11 = (float)(tmp_rot[4]);
1845         this.m12 = (float)(tmp_rot[5]);
1846  
1847         this.m20 = (float)(tmp_rot[6]);
1848         this.m21 = (float)(tmp_rot[7]);
1849         this.m22 = (float)(tmp_rot[8]);
1850
1851     }
1852
1853    /**
1854      * Perform cross product normalization of this matrix.   
1855      */
1856     public final void normalizeCP()
1857     {
1858        float mag = 1.0f/(float)Math.sqrt(m00*m00 + m10*m10 + m20*m20);
1859        m00 = m00*mag;
1860        m10 = m10*mag;
1861        m20 = m20*mag;
1862
1863        mag = 1.0f/(float)Math.sqrt(m01*m01 + m11*m11 + m21*m21);
1864        m01 = m01*mag;
1865        m11 = m11*mag;
1866        m21 = m21*mag;
1867
1868        m02 = m10*m21 - m11*m20;
1869        m12 = m01*m20 - m00*m21;
1870        m22 = m00*m11 - m01*m10;
1871
1872     }
1873
1874    /**
1875      * Perform cross product normalization of matrix m1 and place the 
1876      * normalized values into this.   
1877      * @param m1  Provides the matrix values to be normalized
1878      */
1879     public final void normalizeCP(Matrix3f m1)
1880     {
1881        float mag = 1.0f/(float)Math.sqrt(m1.m00*m1.m00 + m1.m10*m1.m10 + m1.m20*m1.m20);
1882        m00 = m1.m00*mag;
1883        m10 = m1.m10*mag;
1884        m20 = m1.m20*mag;
1885
1886        mag = 1.0f/(float)Math.sqrt(m1.m01*m1.m01 + m1.m11*m1.m11 + m1.m21*m1.m21);
1887        m01 = m1.m01*mag;
1888        m11 = m1.m11*mag;
1889        m21 = m1.m21*mag;
1890
1891        m02 = m10*m21 - m11*m20;
1892        m12 = m01*m20 - m00*m21;
1893        m22 = m00*m11 - m01*m10;
1894
1895     }
1896
1897    /**
1898      * Returns true if all of the data members of Matrix3f m1 are
1899      * equal to the corresponding data members in this Matrix3f.
1900      * @param m1  the matrix with which the comparison is made
1901      * @return  true or false
1902      */  
1903     public boolean equals(Matrix3f m1)
1904     {
1905       try {
1906
1907         return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
1908             && this.m10 == m1.m10 && this.m11 == m1.m11 && this.m12 == m1.m12
1909             && this.m20 == m1.m20 && this.m21 == m1.m21 && this.m22 == m1.m22);
1910       }  
1911       catch (NullPointerException e2) { return false; }
1912
1913     }
1914
1915    /**
1916      * Returns true if the Object o1 is of type Matrix3f and all of the
1917      * data members of o1 are equal to the corresponding data members in
1918      * this Matrix3f.
1919      * @param o1  the object with which the comparison is made
1920      * @return  true or false
1921      */  
1922     public boolean equals(Object o1)
1923     {
1924       try { 
1925
1926            Matrix3f m2 = (Matrix3f) o1;
1927            return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
1928              && this.m10 == m2.m10 && this.m11 == m2.m11 && this.m12 == m2.m12
1929              && this.m20 == m2.m20 && this.m21 == m2.m21 && this.m22 == m2.m22);
1930         }
1931         catch (ClassCastException   e1) { return false; } 
1932         catch (NullPointerException e2) { return false; }
1933     }
1934
1935    /**
1936      * Returns true if the L-infinite distance between this matrix 
1937      * and matrix m1 is less than or equal to the epsilon parameter, 
1938      * otherwise returns false.  The L-infinite
1939      * distance is equal to 
1940      * MAX[i=0,1,2 ; j=0,1,2 ; abs(this.m(i,j) - m1.m(i,j)]
1941      * @param m1  the matrix to be compared to this matrix
1942      * @param epsilon  the threshold value  
1943      */
1944     public boolean epsilonEquals(Matrix3f m1, float epsilon)
1945     {
1946         boolean status = true;
1947
1948         if( Math.abs( this.m00 - m1.m00) > epsilon) status = false;
1949         if( Math.abs( this.m01 - m1.m01) > epsilon) status = false;
1950         if( Math.abs( this.m02 - m1.m02) > epsilon) status = false;
1951
1952         if( Math.abs( this.m10 - m1.m10) > epsilon) status = false;
1953         if( Math.abs( this.m11 - m1.m11) > epsilon) status = false;
1954         if( Math.abs( this.m12 - m1.m12) > epsilon) status = false;
1955
1956         if( Math.abs( this.m20 - m1.m20) > epsilon) status = false;
1957         if( Math.abs( this.m21 - m1.m21) > epsilon) status = false;
1958         if( Math.abs( this.m22 - m1.m22) > epsilon) status = false;
1959
1960         return( status );
1961
1962     }
1963
1964
1965     /**
1966      * Returns a hash code value based on the data values in this
1967      * object.  Two different Matrix3f objects with identical data values
1968      * (i.e., Matrix3f.equals returns true) will return the same hash
1969      * code value.  Two objects with different data members may return the
1970      * same hash value, although this is not likely.
1971      * @return the integer hash code value
1972      */  
1973     public int hashCode() {
1974         long bits = 1L;
1975         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m00);
1976         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m01);
1977         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m02);
1978         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m10);
1979         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m11);
1980         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m12);
1981         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m20);
1982         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m21);
1983         bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m22);
1984         return (int) (bits ^ (bits >> 32));
1985     }
1986
1987
1988   /**
1989     *  Sets this matrix to all zeros.
1990     */
1991    public final void setZero()
1992    {
1993         m00 = 0.0f;
1994         m01 = 0.0f;
1995         m02 = 0.0f;
1996  
1997         m10 = 0.0f;
1998         m11 = 0.0f;
1999         m12 = 0.0f;
2000  
2001         m20 = 0.0f;
2002         m21 = 0.0f;
2003         m22 = 0.0f;
2004
2005    }
2006
2007    /**
2008      * Negates the value of this matrix: this = -this.
2009      */  
2010     public final void negate()
2011     {
2012         this.m00 = -this.m00;
2013         this.m01 = -this.m01;
2014         this.m02 = -this.m02;
2015  
2016         this.m10 = -this.m10;
2017         this.m11 = -this.m11;
2018         this.m12 = -this.m12;
2019  
2020         this.m20 = -this.m20;
2021         this.m21 = -this.m21;
2022         this.m22 = -this.m22;
2023
2024     }
2025
2026    /**
2027      *  Sets the value of this matrix equal to the negation of
2028      *  of the Matrix3f parameter.
2029      *  @param m1  the source matrix
2030      */  
2031     public final void negate(Matrix3f m1)
2032     {
2033         this.m00 = -m1.m00;
2034         this.m01 = -m1.m01;
2035         this.m02 = -m1.m02;
2036  
2037         this.m10 = -m1.m10;
2038         this.m11 = -m1.m11;
2039         this.m12 = -m1.m12;
2040  
2041         this.m20 = -m1.m20;
2042         this.m21 = -m1.m21;
2043         this.m22 = -m1.m22;
2044
2045     }
2046
2047    /**
2048     * Multiply this matrix by the tuple t and place the result
2049     * back into the tuple (t = this*t).
2050     * @param t  the tuple to be multiplied by this matrix and then replaced
2051     */
2052     public final void transform(Tuple3f t) {
2053      float x,y,z;
2054      x = m00* t.x + m01*t.y + m02*t.z; 
2055      y = m10* t.x + m11*t.y + m12*t.z; 
2056      z = m20* t.x + m21*t.y + m22*t.z; 
2057      t.set(x,y,z);
2058     }
2059
2060    /**
2061     * Multiply this matrix by the tuple t and and place the result 
2062     * into the tuple "result" (result = this*t).
2063     * @param t  the tuple to be multiplied by this matrix
2064     * @param result  the tuple into which the product is placed
2065     */
2066     public final void transform(Tuple3f t, Tuple3f result) { 
2067      float x,y,z;
2068      x = m00* t.x + m01*t.y + m02*t.z; 
2069      y = m10* t.x + m11*t.y + m12*t.z;
2070      result.z = m20* t.x + m21*t.y + m22*t.z; 
2071      result.x = x;
2072      result.y = y;
2073     }   
2074
2075     /**
2076      * perform SVD (if necessary to get rotational component 
2077      */
2078     void  getScaleRotate( double[] scales, double[] rot ) {
2079         
2080         double[]    tmp = new double[9];  // scratch matrix
2081         tmp[0] = m00;
2082         tmp[1] = m01;
2083         tmp[2] = m02;
2084         tmp[3] = m10;
2085         tmp[4] = m11;
2086         tmp[5] = m12;
2087         tmp[6] = m20;
2088         tmp[7] = m21;
2089         tmp[8] = m22;
2090         Matrix3d.compute_svd(tmp, scales, rot);
2091
2092         return;
2093        
2094     }
2095
2096     /**
2097      * Creates a new object of the same class as this object.
2098      *
2099      * @return a clone of this instance.
2100      * @exception OutOfMemoryError if there is not enough memory.
2101      * @see java.lang.Cloneable
2102      * @since vecmath 1.3
2103      */
2104     public Object clone() {
2105         Matrix3f m1 = null;
2106         try {
2107             m1 = (Matrix3f)super.clone();
2108         } catch (CloneNotSupportedException e) {
2109             // this shouldn't happen, since we are Cloneable
2110             throw new InternalError();
2111         }
2112         return m1;
2113     }
2114
2115     
2116     /**
2117          * Get the first matrix element in the first row.
2118          * 
2119          * @return Returns the m00.
2120          * 
2121          * @since vecmath 1.5
2122          */
2123         public final  float getM00() {
2124                 return m00;
2125         }
2126
2127         /**
2128          * Set the first matrix element in the first row.
2129          * 
2130          * @param m00 The m00 to set.
2131          * 
2132          * @since vecmath 1.5
2133          */
2134         public final  void setM00(float m00) {
2135                 this.m00 = m00;
2136         }
2137
2138         /**
2139          * Get the second matrix element in the first row.
2140          * 
2141          * @return Returns the m01.
2142          * 
2143          * 
2144          * @since vecmath 1.5
2145          */
2146         public final  float getM01() {
2147                 return m01;
2148         }
2149
2150         /**
2151          * Set the second matrix element in the first row.
2152          * 
2153          * @param m01 The m01 to set.
2154          * 
2155          * @since vecmath 1.5
2156          */
2157         public  final void setM01(float m01) {
2158                 this.m01 = m01;
2159         }
2160
2161         /**
2162          * Get the third matrix element in the first row.
2163          * 
2164          * @return Returns the m02.
2165          * 
2166          * @since vecmath 1.5
2167          */
2168         public final float getM02() {
2169                 return m02;
2170         }
2171
2172         /**
2173          * Set the third matrix element in the first row.
2174          * 
2175          * @param m02 The m02 to set.
2176          * 
2177          * @since vecmath 1.5
2178          */
2179         public final  void setM02(float m02) {
2180                 this.m02 = m02;
2181         }
2182
2183         /**
2184          * Get first matrix element in the second row.
2185          * 
2186          * @return Returns the m10.
2187          * 
2188          * @since vecmath 1.5
2189          */
2190         public final  float getM10() {
2191                 return m10;
2192         }
2193
2194         /**
2195          * Set first matrix element in the second row.
2196          * 
2197          * @param m10 The m10 to set.
2198          * 
2199          * @since vecmath 1.5
2200          */
2201         public final  void setM10(float m10) {
2202                 this.m10 = m10;
2203         }
2204
2205         /**
2206          * Get second matrix element in the second row.
2207          * 
2208          * @return Returns the m11.
2209          * 
2210          * @since vecmath 1.5
2211          */
2212         public final  float getM11() {
2213                 return m11;
2214         }
2215
2216         /**
2217          * Set the second matrix element in the second row.
2218          * 
2219          * @param m11 The m11 to set.
2220          * 
2221          * @since vecmath 1.5
2222          */
2223         public final  void setM11(float m11) {
2224                 this.m11 = m11;
2225         }
2226
2227         /**
2228          * Get the third matrix element in the second row.
2229          * 
2230          * @return Returns the m12.
2231          * 
2232          * @since vecmath 1.5
2233          */
2234         public final  float getM12() {
2235                 return m12;
2236         }
2237
2238         /**
2239          * Set the third matrix element in the second row.
2240          * @param m12 The m12 to set.
2241          * @since vecmath 1.5
2242          */
2243         public final  void setM12(float m12) {
2244                 this.m12 = m12;
2245         }
2246
2247         /**
2248          * Get the first matrix element in the third row.
2249          * 
2250          * @return Returns the m20.
2251          * 
2252          * @since vecmath 1.5
2253          */
2254         public final  float getM20() {
2255                 return m20;
2256         }
2257
2258         /**
2259          * Set the first matrix element in the third row.
2260          * 
2261          * @param m20 The m20 to set.
2262          * 
2263          * @since vecmath 1.5
2264          */
2265         public final void setM20(float m20) {
2266                 this.m20 = m20;
2267         }
2268
2269         /**
2270          * Get the second matrix element in the third row.
2271          * 
2272          * @return Returns the m21.
2273          * 
2274          * @since vecmath 1.5
2275          */
2276         public final float getM21() {
2277                 return m21;
2278         }
2279
2280         /**
2281          * Set the second matrix element in the third row.
2282          * 
2283          * @param m21 The m21 to set.
2284          * 
2285          * @since vecmath 1.5 
2286          */
2287         public final void setM21(float m21) {
2288                 this.m21 = m21;
2289         }
2290
2291         /**
2292          * Get the third matrix element in the third row .
2293          * 
2294          * @return Returns the m22.
2295          * 
2296          * @since vecmath 1.5
2297          */
2298         public final float getM22() {
2299                 return m22;
2300         }
2301
2302         /**
2303          * Set the third matrix element in the third row.
2304          * 
2305          * @param m22 The m22 to set.
2306          * 
2307          * @since vecmath 1.5
2308          */
2309         public final void setM22(float m22) {
2310                 this.m22 = m22;
2311         }
2312
2313 }