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