2 Copyright (C) 1997,1998,1999
3 Kenji Hiranabe, Eiwa System Management, Inc.
5 This program is free software.
6 Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
7 conforming to the Java(TM) 3D API specification by Sun Microsystems.
9 Permission to use, copy, modify, distribute and sell this software
10 and its documentation for any purpose is hereby granted without fee,
11 provided that the above copyright notice appear in all copies and
12 that both that copyright notice and this permission notice appear
13 in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
14 makes no representations about the suitability of this software for any
15 purpose. It is provided "AS IS" with NO WARRANTY.
20 * A single precision floating point 4 by 4 matrix.
22 * @author Kenji hiranabe
24 * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
25 * constructor and method names for the optimization of compiled
26 * JavaScript using Java2Script.
29 public class M4 extends M34 {
32 * The fourth element of the first row.
37 * The fourth element of the second row.
42 * The fourth element of the third row.
47 * The first element of the fourth row.
52 * The second element of the fourth row.
57 * The third element of the fourth row.
62 * The fourth element of the fourth row.
69 * Constructs and initializes a Matrix4f from the specified 16 element array.
70 * this.m00 =v[0], this.m01=v[1], etc.
73 * the array of length 16 containing in order
76 public static M4 newA16(float[] v) {
102 * Constructs a new matrix with the same values as the Matrix4f parameter.
108 public static M4 newM4(M4 m1) {
126 * Constructs and initializes a Matrix4f from the rotation matrix and
130 * The rotation matrix representing the rotational components
132 * The translational components of the matrix
135 public static M4 newMV(M3 m1, T3 t) {
142 * Sets this matrix to all zeros.
144 public void setZero() {
146 m03 = m13 = m23 = m30 = m31 = m32 = m33 = 0.0f;
150 * Sets this Matrix4f to identity.
152 public void setIdentity() {
154 m00 = m11 = m22 = m33 = 1.0f;
158 * Sets the value of this matrix to a copy of the passed matrix m1.
161 * the matrix to be copied
164 public M4 setM4(M4 m1) {
177 * Initializes a Matrix4f from the rotation matrix and translation.
180 * The rotation matrix representing the rotational components
182 * The translational components of the matrix
184 public void setMV(M3 m1, T3 t) {
191 * Sets the rotational component (upper 3x3) of this matrix to the matrix
192 * values in the single precision Matrix3f argument; the other elements of
193 * this matrix are initialized as if this were an identity matrix (ie, affine
194 * matrix with no translational component).
199 public void setToM3(M34 m1) {
201 m03 = m13 = m23 = m30 = m31 = m32 = 0.0f;
206 * Sets the rotational component (upper 3x3) of this matrix
207 * to a rotation given by an axis angle
210 * the axis and angle to be converted
212 public void setToAA(A4 a) {
218 * Sets the values in this Matrix4f equal to the row-major array parameter
219 * (ie, the first four elements of the array will be copied into the first row
220 * of this matrix, etc.).
224 public void setA(float m[]) {
244 * Modifies the translational components of this matrix to the values of the
245 * Vector3f argument; the other values of this matrix are not modified.
248 * the translational component
250 public void setTranslation(T3 trans) {
257 * Sets the specified element of this matrix4f to the value provided.
260 * the row number to be modified (zero indexed)
262 * the column number to be modified (zero indexed)
266 public void setElement(int row, int col, float v) {
267 if (row < 3 && col < 3) {
271 if (row > 3 || col > 3)
301 * Retrieves the value at the specified row and column of this matrix.
304 * the row number to be retrieved (zero indexed)
306 * the column number to be retrieved (zero indexed)
307 * @return the value at the indexed element
309 public float getElement(int row, int col) {
310 if (row < 3 && col < 3)
311 return get33(row, col);
312 if (row > 3 || col > 3) {
338 * Retrieves the translational components of this matrix.
341 * the vector that will receive the translational component
343 public void getTranslation(T3 trans) {
350 * Gets the upper 3x3 values of this matrix and places them into the matrix
354 * The matrix that will hold the values
356 public void getRotationScale(M3 m1) {
369 * Replaces the upper 3x3 matrix values of this matrix with the values in the
373 * The matrix that will be the new upper 3x3
375 public void setRotationScale(M3 m1) {
388 * Sets the specified row of this matrix4f to the four values provided.
391 * the row number to be modified (zero indexed)
393 * the replacement row
395 public void setRowA(int row, float v[]) {
419 * Copies the matrix values in the specified row into the array parameter.
424 * The array into which the matrix row values will be copied
427 public void getRow(int row, float v[]) {
451 * Sets the specified column of this matrix4f to the four values provided.
454 * the column number to be modified (zero indexed)
456 * the first row element
458 * the second row element
460 * the third row element
462 * the fourth row element
464 public void setColumn4(int column, float x, float y, float z, float w) {
470 } else if (column == 1) {
475 } else if (column == 2) {
480 } else if (column == 3) {
491 * Sets the specified column of this matrix4f to the four values provided.
494 * the column number to be modified (zero indexed)
496 * the replacement column
498 public void setColumnA(int column, float v[]) {
500 setColumn33(column, v);
523 * Copies the matrix values in the specified column into the array parameter.
528 * The array into which the matrix column values will be copied
530 public void getColumn(int column, float v[]) {
532 getColumn33(column, v);
555 * Sets the value of this matrix to the matrix difference of itself and matrix
556 * m1 (this = this - m1).
561 public void sub(M4 m1) {
573 * Sets the value of this matrix to its transpose.
575 public void transpose() {
591 * Sets the value of this matrix to its inverse.
595 float s = determinant4();
600 // less *,+,- calculation than expanded expression.
601 set(m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13
602 * (m21 * m32 - m22 * m31), m21 * (m02 * m33 - m03 * m32) + m22
603 * (m03 * m31 - m01 * m33) + m23 * (m01 * m32 - m02 * m31), m31
604 * (m02 * m13 - m03 * m12) + m32 * (m03 * m11 - m01 * m13) + m33
605 * (m01 * m12 - m02 * m11), m01 * (m13 * m22 - m12 * m23) + m02
606 * (m11 * m23 - m13 * m21) + m03 * (m12 * m21 - m11 * m22),
608 m12 * (m20 * m33 - m23 * m30) + m13 * (m22 * m30 - m20 * m32) + m10
609 * (m23 * m32 - m22 * m33), m22 * (m00 * m33 - m03 * m30) + m23
610 * (m02 * m30 - m00 * m32) + m20 * (m03 * m32 - m02 * m33), m32
611 * (m00 * m13 - m03 * m10) + m33 * (m02 * m10 - m00 * m12) + m30
612 * (m03 * m12 - m02 * m13), m02 * (m13 * m20 - m10 * m23) + m03
613 * (m10 * m22 - m12 * m20) + m00 * (m12 * m23 - m13 * m22),
615 m13 * (m20 * m31 - m21 * m30) + m10 * (m21 * m33 - m23 * m31) + m11
616 * (m23 * m30 - m20 * m33), m23 * (m00 * m31 - m01 * m30) + m20
617 * (m01 * m33 - m03 * m31) + m21 * (m03 * m30 - m00 * m33), m33
618 * (m00 * m11 - m01 * m10) + m30 * (m01 * m13 - m03 * m11) + m31
619 * (m03 * m10 - m00 * m13), m03 * (m11 * m20 - m10 * m21) + m00
620 * (m13 * m21 - m11 * m23) + m01 * (m10 * m23 - m13 * m20),
622 m10 * (m22 * m31 - m21 * m32) + m11 * (m20 * m32 - m22 * m30) + m12
623 * (m21 * m30 - m20 * m31), m20 * (m02 * m31 - m01 * m32) + m21
624 * (m00 * m32 - m02 * m30) + m22 * (m01 * m30 - m00 * m31), m30
625 * (m02 * m11 - m01 * m12) + m31 * (m00 * m12 - m02 * m10) + m32
626 * (m01 * m10 - m00 * m11), m00 * (m11 * m22 - m12 * m21) + m01
627 * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20));
652 private void set(float m00, float m01, float m02, float m03, float m10,
653 float m11, float m12, float m13, float m20, float m21,
654 float m22, float m23, float m30, float m31, float m32,
674 * Computes the determinant of this matrix.
676 * @return the determinant of the matrix
678 public float determinant4() {
679 // less *,+,- calculation than expanded expression.
680 return (m00 * m11 - m01 * m10) * (m22 * m33 - m23 * m32)
681 - (m00 * m12 - m02 * m10) * (m21 * m33 - m23 * m31)
682 + (m00 * m13 - m03 * m10) * (m21 * m32 - m22 * m31)
683 + (m01 * m12 - m02 * m11) * (m20 * m33 - m23 * m30)
684 - (m01 * m13 - m03 * m11) * (m20 * m32 - m22 * m30)
685 + (m02 * m13 - m03 * m12) * (m20 * m31 - m21 * m30);
690 * Multiplies each element of this matrix by a scalar.
693 * The scalar multiplier.
695 public void scale(float scalar) {
707 * Sets the value of this matrix to the result of multiplying itself with
713 public void mul(M4 m1) {
718 * Sets the value of this matrix to the result of multiplying the two argument
726 public void mul2(M4 m1, M4 m2) {
728 set(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30,
729 m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31,
730 m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32,
731 m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33,
733 m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30,
734 m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31,
735 m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32,
736 m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33,
738 m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30,
739 m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31,
740 m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32,
741 m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33,
743 m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30,
744 m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31,
745 m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32,
746 m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33);
750 * Transform the vector vec using this Matrix4f and place the result back into
754 * the single precision vector to be transformed
756 public void transform(T4 vec) {
757 transform2(vec, vec);
761 * Transform the vector vec using this Matrix4f and place the result into
765 * the single precision vector to be transformed
767 * the vector into which the transformed values are placed
769 public void transform2(T4 vec, T4 vecOut) {
771 vecOut.set4(m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, m10
772 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, m20 * vec.x + m21
773 * vec.y + m22 * vec.z + m23 * vec.w, m30 * vec.x + m31 * vec.y + m32
774 * vec.z + m33 * vec.w);
778 * Transforms the point parameter with this Matrix4f and places the result
779 * back into point. The fourth element of the point input parameter is assumed
783 * the input point to be transformed.
785 public void rotTrans(T3 point) {
786 rotTrans2(point, point);
790 * Transforms the point parameter with this Matrix4f and places the result
791 * into pointOut. The fourth element of the point input parameter is assumed to
792 * be one. point may be pointOut
795 * the input point to be transformed.
797 * the transformed point
800 public T3 rotTrans2(T3 point, T3 pointOut) {
802 m00 * point.x + m01 * point.y + m02 * point.z + m03,
803 m10 * point.x + m11 * point.y + m12 * point.z + m13,
804 m20 * point.x + m21 * point.y + m22 * point.z + m23);
809 * Sets the value of this matrix to a rotation matrix about the w axis by the
813 * the angle to rotate about the W axis in radians
816 public M4 setAsXYRotation(float angle) {
818 double c = Math.cos(angle);
819 double s = Math.sin(angle);
828 * Sets the value of this matrix to a rotation matrix about the w axis by the
832 * the angle to rotate about the W axis in radians
835 public M4 setAsYZRotation(float angle) {
837 double c = Math.cos(angle);
838 double s = Math.sin(angle);
847 * Sets the value of this matrix to a rotation matrix about the w axis by the
851 * the angle to rotate about the W axis in radians
854 public M4 setAsXZRotation(float angle) {
856 double c = Math.cos(angle);
857 double s = Math.sin(angle);
866 * Returns true if the Object o is of type Matrix4f and all of the data
867 * members of t1 are equal to the corresponding data members in this Matrix4f.
870 * the object with which the comparison is made.
873 public boolean equals(Object o) {
874 if (!(o instanceof M4))
877 return (this.m00 == m.m00 && this.m01 == m.m01 && this.m02 == m.m02
878 && this.m03 == m.m03 && this.m10 == m.m10 && this.m11 == m.m11
879 && this.m12 == m.m12 && this.m13 == m.m13 && this.m20 == m.m20
880 && this.m21 == m.m21 && this.m22 == m.m22 && this.m23 == m.m23
881 && this.m30 == m.m30 && this.m31 == m.m31 && this.m32 == m.m32 && this.m33 == m.m33);
885 * Returns a hash number based on the data values in this object. Two
886 * different Matrix4f objects with identical data values (ie, returns true for
887 * equals(Matrix4f) ) will return the same hash number. Two objects with
888 * different data members may return the same hash value, although this is not
891 * @return the integer hash value
894 public int hashCode() {
895 return T3.floatToIntBits(m00) ^ T3.floatToIntBits(m01)
896 ^ T3.floatToIntBits(m02) ^ T3.floatToIntBits(m03)
897 ^ T3.floatToIntBits(m10) ^ T3.floatToIntBits(m11)
898 ^ T3.floatToIntBits(m12) ^ T3.floatToIntBits(m13)
899 ^ T3.floatToIntBits(m20) ^ T3.floatToIntBits(m21)
900 ^ T3.floatToIntBits(m22) ^ T3.floatToIntBits(m23)
901 ^ T3.floatToIntBits(m30) ^ T3.floatToIntBits(m31)
902 ^ T3.floatToIntBits(m32) ^ T3.floatToIntBits(m33);
906 * Returns a string that contains the values of this Matrix4f.
908 * @return the String representation
911 public String toString() {
912 return "[\n [" + m00 + "\t" + m01 + "\t" + m02 + "\t" + m03 + "]"
913 + "\n [" + m10 + "\t" + m11 + "\t" + m12 + "\t" + m13 + "]" + "\n ["
914 + m20 + "\t" + m21 + "\t" + m22 + "\t" + m23 + "]" + "\n [" + m30
915 + "\t" + m31 + "\t" + m32 + "\t" + m33 + "] ]";
917 public M4 round(float f) {
937 private float rnd(float n, float f) {
938 return (Math.abs(n) < f ? 0 : n);