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
28 public class M4 extends M34 {
31 * The fourth element of the first row.
36 * The fourth element of the second row.
41 * The fourth element of the third row.
46 * The first element of the fourth row.
51 * The second element of the fourth row.
56 * The third element of the fourth row.
61 * The fourth element of the fourth row.
72 * Constructs and initializes a Matrix4f from the specified 16 element array.
73 * this.m00 =v[0], this.m01=v[1], etc.
76 * the array of length 16 containing in order
79 public static M4 newA16(float[] v) {
105 * Constructs a new matrix with the same values as the Matrix4f parameter.
111 public static M4 newM4(M4 m1) {
129 * Constructs and initializes a Matrix4f from the rotation matrix and
133 * The rotation matrix representing the rotational components
135 * The translational components of the matrix
138 public static M4 newMV(M3 m1, T3 t) {
145 * Sets this matrix to all zeros.
147 public void setZero() {
149 m03 = m13 = m23 = m30 = m31 = m32 = m33 = 0.0f;
153 * Sets this Matrix4f to identity.
155 public void setIdentity() {
157 m00 = m11 = m22 = m33 = 1.0f;
161 * Sets the value of this matrix to a copy of the passed matrix m1.
164 * the matrix to be copied
167 public M4 setM4(M4 m1) {
180 * Initializes a Matrix4f from the rotation matrix and translation.
183 * The rotation matrix representing the rotational components
185 * The translational components of the matrix
187 public void setMV(M3 m1, T3 t) {
194 * Sets the rotational component (upper 3x3) of this matrix to the matrix
195 * values in the single precision Matrix3f argument; the other elements of
196 * this matrix are initialized as if this were an identity matrix (ie, affine
197 * matrix with no translational component).
202 public void setToM3(M34 m1) {
204 m03 = m13 = m23 = m30 = m31 = m32 = 0.0f;
209 * Sets the rotational component (upper 3x3) of this matrix
210 * to a rotation given by an axis angle
213 * the axis and angle to be converted
215 public void setToAA(A4 a) {
221 * Sets the values in this Matrix4f equal to the row-major array parameter
222 * (ie, the first four elements of the array will be copied into the first row
223 * of this matrix, etc.).
227 public void setA(float m[]) {
247 * Modifies the translational components of this matrix to the values of the
248 * Vector3f argument; the other values of this matrix are not modified.
251 * the translational component
253 public void setTranslation(T3 trans) {
260 * Sets the specified element of this matrix4f to the value provided.
263 * the row number to be modified (zero indexed)
265 * the column number to be modified (zero indexed)
269 public void setElement(int row, int col, float v) {
270 if (row < 3 && col < 3) {
274 if (row > 3 || col > 3)
304 * Retrieves the value at the specified row and column of this matrix.
307 * the row number to be retrieved (zero indexed)
309 * the column number to be retrieved (zero indexed)
310 * @return the value at the indexed element
312 public float getElement(int row, int col) {
313 if (row < 3 && col < 3)
314 return get33(row, col);
315 if (row > 3 || col > 3) {
341 * Retrieves the translational components of this matrix.
344 * the vector that will receive the translational component
346 public void getTranslation(T3 trans) {
353 * Gets the upper 3x3 values of this matrix and places them into the matrix
357 * The matrix that will hold the values
359 public void getRotationScale(M3 m1) {
372 * Replaces the upper 3x3 matrix values of this matrix with the values in the
376 * The matrix that will be the new upper 3x3
378 public void setRotationScale(M3 m1) {
391 * Sets the specified row of this matrix4f to the four values provided.
394 * the row number to be modified (zero indexed)
396 * the replacement row
398 public void setRowA(int row, float v[]) {
422 * Copies the matrix values in the specified row into the array parameter.
427 * The array into which the matrix row values will be copied
430 public void getRow(int row, float v[]) {
454 * Sets the specified column of this matrix4f to the four values provided.
457 * the column number to be modified (zero indexed)
459 * the first row element
461 * the second row element
463 * the third row element
465 * the fourth row element
467 public void setColumn4(int column, float x, float y, float z, float w) {
473 } else if (column == 1) {
478 } else if (column == 2) {
483 } else if (column == 3) {
494 * Sets the specified column of this matrix4f to the four values provided.
497 * the column number to be modified (zero indexed)
499 * the replacement column
501 public void setColumnA(int column, float v[]) {
503 setColumn33(column, v);
526 * Copies the matrix values in the specified column into the array parameter.
531 * The array into which the matrix column values will be copied
533 public void getColumn(int column, float v[]) {
535 getColumn33(column, v);
558 * Sets the value of this matrix to the matrix difference of itself and matrix
559 * m1 (this = this - m1).
564 public void sub(M4 m1) {
576 * Sets the value of this matrix to its transpose.
578 public void transpose() {
594 * Sets the value of this matrix to its inverse.
598 float s = determinant4();
603 // less *,+,- calculation than expanded expression.
604 set(m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13
605 * (m21 * m32 - m22 * m31), m21 * (m02 * m33 - m03 * m32) + m22
606 * (m03 * m31 - m01 * m33) + m23 * (m01 * m32 - m02 * m31), m31
607 * (m02 * m13 - m03 * m12) + m32 * (m03 * m11 - m01 * m13) + m33
608 * (m01 * m12 - m02 * m11), m01 * (m13 * m22 - m12 * m23) + m02
609 * (m11 * m23 - m13 * m21) + m03 * (m12 * m21 - m11 * m22),
611 m12 * (m20 * m33 - m23 * m30) + m13 * (m22 * m30 - m20 * m32) + m10
612 * (m23 * m32 - m22 * m33), m22 * (m00 * m33 - m03 * m30) + m23
613 * (m02 * m30 - m00 * m32) + m20 * (m03 * m32 - m02 * m33), m32
614 * (m00 * m13 - m03 * m10) + m33 * (m02 * m10 - m00 * m12) + m30
615 * (m03 * m12 - m02 * m13), m02 * (m13 * m20 - m10 * m23) + m03
616 * (m10 * m22 - m12 * m20) + m00 * (m12 * m23 - m13 * m22),
618 m13 * (m20 * m31 - m21 * m30) + m10 * (m21 * m33 - m23 * m31) + m11
619 * (m23 * m30 - m20 * m33), m23 * (m00 * m31 - m01 * m30) + m20
620 * (m01 * m33 - m03 * m31) + m21 * (m03 * m30 - m00 * m33), m33
621 * (m00 * m11 - m01 * m10) + m30 * (m01 * m13 - m03 * m11) + m31
622 * (m03 * m10 - m00 * m13), m03 * (m11 * m20 - m10 * m21) + m00
623 * (m13 * m21 - m11 * m23) + m01 * (m10 * m23 - m13 * m20),
625 m10 * (m22 * m31 - m21 * m32) + m11 * (m20 * m32 - m22 * m30) + m12
626 * (m21 * m30 - m20 * m31), m20 * (m02 * m31 - m01 * m32) + m21
627 * (m00 * m32 - m02 * m30) + m22 * (m01 * m30 - m00 * m31), m30
628 * (m02 * m11 - m01 * m12) + m31 * (m00 * m12 - m02 * m10) + m32
629 * (m01 * m10 - m00 * m11), m00 * (m11 * m22 - m12 * m21) + m01
630 * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20));
655 private void set(float m00, float m01, float m02, float m03, float m10,
656 float m11, float m12, float m13, float m20, float m21,
657 float m22, float m23, float m30, float m31, float m32,
677 * Computes the determinant of this matrix.
679 * @return the determinant of the matrix
681 public float determinant4() {
682 // less *,+,- calculation than expanded expression.
683 return (m00 * m11 - m01 * m10) * (m22 * m33 - m23 * m32)
684 - (m00 * m12 - m02 * m10) * (m21 * m33 - m23 * m31)
685 + (m00 * m13 - m03 * m10) * (m21 * m32 - m22 * m31)
686 + (m01 * m12 - m02 * m11) * (m20 * m33 - m23 * m30)
687 - (m01 * m13 - m03 * m11) * (m20 * m32 - m22 * m30)
688 + (m02 * m13 - m03 * m12) * (m20 * m31 - m21 * m30);
693 * Multiplies each element of this matrix by a scalar.
696 * The scalar multiplier.
698 private void scale(float scalar) {
710 * Sets the value of this matrix to the result of multiplying itself with
716 public void mul(M4 m1) {
721 * Sets the value of this matrix to the result of multiplying the two argument
729 public void mul2(M4 m1, M4 m2) {
731 set(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30,
732 m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31,
733 m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32,
734 m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33,
736 m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30,
737 m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31,
738 m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32,
739 m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33,
741 m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30,
742 m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31,
743 m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32,
744 m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33,
746 m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30,
747 m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31,
748 m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32,
749 m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33);
753 * Transform the vector vec using this Matrix4f and place the result back into
757 * the single precision vector to be transformed
759 public void transform(T4 vec) {
760 transform2(vec, vec);
764 * Transform the vector vec using this Matrix4f and place the result into
768 * the single precision vector to be transformed
770 * the vector into which the transformed values are placed
772 public void transform2(T4 vec, T4 vecOut) {
774 vecOut.set4(m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, m10
775 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, m20 * vec.x + m21
776 * vec.y + m22 * vec.z + m23 * vec.w, m30 * vec.x + m31 * vec.y + m32
777 * vec.z + m33 * vec.w);
781 * Transforms the point parameter with this Matrix4f and places the result
782 * back into point. The fourth element of the point input parameter is assumed
786 * the input point to be transformed.
788 public void rotTrans(T3 point) {
789 rotTrans2(point, point);
793 * Transforms the point parameter with this Matrix4f and places the result
794 * into pointOut. The fourth element of the point input parameter is assumed to
795 * be one. point may be pointOut
798 * the input point to be transformed.
800 * the transformed point
803 public T3 rotTrans2(T3 point, T3 pointOut) {
805 m00 * point.x + m01 * point.y + m02 * point.z + m03,
806 m10 * point.x + m11 * point.y + m12 * point.z + m13,
807 m20 * point.x + m21 * point.y + m22 * point.z + m23);
812 * Sets the value of this matrix to a rotation matrix about the w axis by the
816 * the angle to rotate about the W axis in radians
819 public M4 setAsXYRotation(float angle) {
821 double c = Math.cos(angle);
822 double s = Math.sin(angle);
831 * Sets the value of this matrix to a rotation matrix about the w axis by the
835 * the angle to rotate about the W axis in radians
838 public M4 setAsYZRotation(float angle) {
840 double c = Math.cos(angle);
841 double s = Math.sin(angle);
850 * Sets the value of this matrix to a rotation matrix about the w axis by the
854 * the angle to rotate about the W axis in radians
857 public M4 setAsXZRotation(float angle) {
859 double c = Math.cos(angle);
860 double s = Math.sin(angle);
869 * Returns true if the Object o is of type Matrix4f and all of the data
870 * members of t1 are equal to the corresponding data members in this Matrix4f.
873 * the object with which the comparison is made.
876 public boolean equals(Object o) {
877 if (!(o instanceof M4))
880 return (this.m00 == m.m00 && this.m01 == m.m01 && this.m02 == m.m02
881 && this.m03 == m.m03 && this.m10 == m.m10 && this.m11 == m.m11
882 && this.m12 == m.m12 && this.m13 == m.m13 && this.m20 == m.m20
883 && this.m21 == m.m21 && this.m22 == m.m22 && this.m23 == m.m23
884 && this.m30 == m.m30 && this.m31 == m.m31 && this.m32 == m.m32 && this.m33 == m.m33);
888 * Returns a hash number based on the data values in this object. Two
889 * different Matrix4f objects with identical data values (ie, returns true for
890 * equals(Matrix4f) ) will return the same hash number. Two objects with
891 * different data members may return the same hash value, although this is not
894 * @return the integer hash value
897 public int hashCode() {
898 return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)
899 ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m03)
900 ^ T3.floatToIntBits0(m10) ^ T3.floatToIntBits0(m11)
901 ^ T3.floatToIntBits0(m12) ^ T3.floatToIntBits0(m13)
902 ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)
903 ^ T3.floatToIntBits0(m22) ^ T3.floatToIntBits0(m23)
904 ^ T3.floatToIntBits0(m30) ^ T3.floatToIntBits0(m31)
905 ^ T3.floatToIntBits0(m32) ^ T3.floatToIntBits0(m33);
909 * Returns a string that contains the values of this Matrix4f.
911 * @return the String representation
914 public String toString() {
915 return "[\n [" + m00 + "\t" + m01 + "\t" + m02 + "\t" + m03 + "]"
916 + "\n [" + m10 + "\t" + m11 + "\t" + m12 + "\t" + m13 + "]" + "\n ["
917 + m20 + "\t" + m21 + "\t" + m22 + "\t" + m23 + "]" + "\n [" + m30
918 + "\t" + m31 + "\t" + m32 + "\t" + m33 + "] ]";
920 public M4 round(float f) {
940 private float rnd(float n, float f) {
941 return (Math.abs(n) < f ? 0 : n);