diff options
Diffstat (limited to 'demos/MiscDemos/jahuwaldt/gl/Matrix.java')
-rw-r--r-- | demos/MiscDemos/jahuwaldt/gl/Matrix.java | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/demos/MiscDemos/jahuwaldt/gl/Matrix.java b/demos/MiscDemos/jahuwaldt/gl/Matrix.java new file mode 100644 index 0000000..e043197 --- /dev/null +++ b/demos/MiscDemos/jahuwaldt/gl/Matrix.java @@ -0,0 +1,499 @@ +/*
+* Matrix -- Collection of methods for working with 3D transformation matricies.
+*
+* Copyright (C) 2001 by Joseph A. Huwaldt <[email protected]>.
+* All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Library General Public License for more details.
+**/
+
+package jahuwaldt.gl;
+
+
+/**
+* A set of static utility methods for working with matricies.
+* In particular, these methods are geared for working efficiently
+* with OpenGL transformation matrices.
+*
+* <p> Modified by: Joseph A. Huwaldt </p>
+*
+* @author Joseph A. Huwaldt Date: January 13, 2001
+* @version January 30, 2001
+**/
+public class Matrix {
+
+ /**
+ * The value for Math.PI as a float instead of a double.
+ **/
+ public static final float PI = (float)Math.PI;
+
+ /**
+ * Convert's an angle in radians to one in degrees.
+ *
+ * @param rad The angle in radians to be converted.
+ * @return The angle in degrees.
+ **/
+ public static final float rad2Deg(float rad) {
+ return rad*180/PI;
+ }
+
+ /**
+ * Convert's an angle in degrees to one in radians.
+ *
+ * @param deg The angle in degrees to be converted.
+ * @return The angle in radians.
+ **/
+ public static final float deg2Rad(float deg) {
+ return deg*PI/180;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix to the identity matrix.
+ * Equiv. to: T = I
+ *
+ * I = 1 0 0 0
+ * 0 1 0 0
+ * 0 0 1 0
+ * 0 0 0 1
+ *
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setIdentity(float mtx[]) {
+ mtx[0] = mtx[5] = mtx[10] = mtx[15] = 1;
+ mtx[1] = mtx[2] = mtx[3] = mtx[4] = 0;
+ mtx[6] = mtx[7] = mtx[8] = mtx[9] = 0;
+ mtx[11] = mtx[12] = mtx[13] = mtx[14] = 0;
+
+ return mtx;
+ }
+
+ /**
+ * Create a new 4x4 transformation matrix set to the identity matrix.
+ * Equiv. to: T = I
+ *
+ * I = 1 0 0 0
+ * 0 1 0 0
+ * 0 0 1 0
+ * 0 0 0 1
+ *
+ * @return A reference to a 4x4 identity matrix is returned.
+ **/
+ public static final float[] identity() {
+ float[] mtx = new float[16];
+ mtx[0] = mtx[5] = mtx[10] = mtx[15] = 1;
+ return mtx;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix which rotates about the X-axis.
+ * Equiv. to: T = Rx
+ *
+ * Rx = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the X-axis in radians.
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setRotateX(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+ mtx[0] = 1.0f;
+ mtx[1] = 0.0f;
+ mtx[2] = 0.0f;
+ mtx[3] = 0.0f;
+ mtx[4] = 0.0f;
+ mtx[5] = rcos;
+ mtx[6] = rsin;
+ mtx[7] = 0.0f;
+ mtx[8] = 0.0f;
+ mtx[9] = -rsin;
+ mtx[10] = rcos;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+
+ return mtx;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix which rotates about the Y-axis.
+ * Equiv. to: T = Ry
+ *
+ * Ry = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the Y-axis in radians.
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setRotateY(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+ mtx[0] = rcos;
+ mtx[1] = 0.0f;
+ mtx[2] = -rsin;
+ mtx[3] = 0.0f;
+ mtx[4] = 0.0f;
+ mtx[5] = 1.0f;
+ mtx[6] = 0.0f;
+ mtx[7] = 0.0f;
+ mtx[8] = rsin;
+ mtx[9] = 0.0f;
+ mtx[10] = rcos;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+
+ return mtx;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix which rotates about the Z-axis.
+ * Equiv. to: T = Rz
+ *
+ * Rz = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the Z-axis in radians.
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setRotateZ(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+ mtx[0] = rcos;
+ mtx[1] = rsin;
+ mtx[2] = 0.0f;
+ mtx[3] = 0.0f;
+ mtx[4] = -rsin;
+ mtx[5] = rcos;
+ mtx[6] = 0.0f;
+ mtx[7] = 0.0f;
+ mtx[8] = 0.0f;
+ mtx[9] = 0.0f;
+ mtx[10] = 1.0f;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+
+ return mtx;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix which scales in each
+ * axis direction by the specified scale factors.
+ * Equiv. to: T = S
+ *
+ * S = sx 0 0 0
+ * 0 sy 0 0
+ * 0 0 sz 0
+ * 0 0 0 1
+ *
+ * @param sx The scale factor in the X-axis direction.
+ * @param sy The scale factor in the Y-axis direction.
+ * @param sz The scale factor in the Z-axis direction.
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setScale(float sx, float sy, float sz, float mtx[]) {
+ mtx[0] = sx;
+ mtx[5] = sy;
+ mtx[10] = sz;
+ mtx[15] = 1;
+ mtx[1] = mtx[2] = mtx[3] = mtx[4] = 0;
+ mtx[6] = mtx[7] = mtx[8] = mtx[9] = 0;
+ mtx[11] = mtx[12] = mtx[13] = mtx[14] = 0;
+
+ return mtx;
+ }
+
+ /**
+ * Set a 4x4 transformation matrix which translates in each
+ * axis direction by the specified amounts.
+ * Equiv. to: T = Tr
+ *
+ * Tr = 1 0 0 tx
+ * 0 1 0 ty
+ * 0 0 1 tz
+ * 0 0 0 1
+ *
+ * @param tx The translation amount in the X-axis direction.
+ * @param ty The translation amount in the Y-axis direction.
+ * @param tz The translation amount in the Z-axis direction.
+ * @param mtx The 4x4 matrix to be set.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] setTranslate(float tx, float ty, float tz, float mtx[]) {
+ mtx[0] = 1;
+ mtx[1] = mtx[2] = 0;
+ mtx[3] = tx;
+ mtx[4] = 0;
+ mtx[5] = 1;
+ mtx[6] = 0;
+ mtx[7] = ty;
+ mtx[8] = mtx[9] = 0;
+ mtx[10] = 1;
+ mtx[11] = tz;
+ mtx[12] = mtx[13] = mtx[14] = 0;
+ mtx[15] = 1;
+
+ return mtx;
+ }
+
+ /**
+ * Multiplies two 4x4 matricies together, and returns the
+ * result in a new output matrix. The multiplication is done
+ * fast, at the expense of code.
+ *
+ * @param mtx1 The 1st matrix being multiplied.
+ * @param mtx2 The 2nd matrix being multiplied.
+ * @return The output matrix containing the input matrices multiplied.
+ **/
+ public static final float[] multiply(float mtx1[], float mtx2[]) {
+ float nmtx[] = new float[16];
+
+ float m0 = mtx1[0], m1 = mtx1[1], m2 = mtx1[2], m3 = mtx1[3];
+ nmtx[0] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ nmtx[1] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ nmtx[2] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ nmtx[3] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[4]; m1 = mtx1[5]; m2 = mtx1[6]; m3 = mtx1[7];
+ nmtx[4] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ nmtx[5] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ nmtx[6] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ nmtx[7] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[8]; m1 = mtx1[9]; m2 = mtx1[10]; m3 = mtx1[11];
+ nmtx[8] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ nmtx[9] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ nmtx[10] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ nmtx[11] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[12]; m1 = mtx1[13]; m2 = mtx1[14]; m3 = mtx1[15];
+ nmtx[12] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ nmtx[13] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ nmtx[14] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ nmtx[15] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ return nmtx;
+ }
+
+
+ /**
+ * Multiplies two 4x4 matricies together, and places them
+ * in the specified output matrix. The multiplication is done
+ * fast, at the expense of code. The output matrix may not
+ * be the same as one of the input matrices or the results
+ * are undefined.
+ *
+ * @param mtx1 The 1st matrix being multiplied.
+ * @param mtx2 The 2nd matrix being multiplied.
+ * @param dest The output matrix (results go here). Must not be
+ * one of the input matrices.
+ * @return A reference to the output matrix "dest" is returned.
+ **/
+ public static final float[] multiply(float mtx1[], float mtx2[], float dest[]) {
+
+ float m0 = mtx1[0], m1 = mtx1[1], m2 = mtx1[2], m3 = mtx1[3];
+ dest[0] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ dest[1] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ dest[2] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ dest[3] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[4]; m1 = mtx1[5]; m2 = mtx1[6]; m3 = mtx1[7];
+ dest[4] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ dest[5] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ dest[6] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ dest[7] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[8]; m1 = mtx1[9]; m2 = mtx1[10]; m3 = mtx1[11];
+ dest[8] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ dest[9] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ dest[10] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ dest[11] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ m0 = mtx1[12]; m1 = mtx1[13]; m2 = mtx1[14]; m3 = mtx1[15];
+ dest[12] = m0*mtx2[0] + m1*mtx2[4] + m2*mtx2[8] + m3*mtx2[12];
+ dest[13] = m0*mtx2[1] + m1*mtx2[5] + m2*mtx2[9] + m3*mtx2[13];
+ dest[14] = m0*mtx2[2] + m1*mtx2[6] + m2*mtx2[10] + m3*mtx2[14];
+ dest[15] = m0*mtx2[3] + m1*mtx2[7] + m2*mtx2[11] + m3*mtx2[15];
+
+ return dest;
+ }
+
+ /****************************************************************
+ * The following are matrix post concatenation routines that *
+ * can be used as speedy replacements for the more standard *
+ * matrix mult. routine to generate combined rotations. *
+ ****************************************************************/
+ /**
+ * Multiply an existing 4x4 transformation matrix by an X-axis
+ * rotation matrix quickly. This is much faster than calling
+ * setRotateX() followed by multiply().
+ * Equiv. to: T = T*Rx
+ *
+ * Rx = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the X-axis in radians.
+ * @param mtx The 4x4 matrix to be multiplied by the rotation matrix.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] rotateX(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+
+ for (int i = 0 ; i < 4 ; i++) {
+ int i1 = i*4 + 1;
+ int i2 = i1 + 1;
+ float t = mtx[i1];
+ mtx[i1] = t*rcos - mtx[i2]*rsin;
+ mtx[i2] = t*rsin + mtx[i2]*rcos;
+ }
+
+ return mtx;
+ }
+
+ /**
+ * Multiply an existing 4x4 transformation matrix by a Y-axis
+ * rotation matrix quickly. This is much faster than calling
+ * setRotateY() followed by multiply().
+ * Equiv. to: T = T*Ry
+ *
+ * Ry = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the Y-axis in radians.
+ * @param mtx The 4x4 matrix to be multiplied by the rotation matrix.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] rotateY(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+
+ for (int i = 0 ; i < 4 ; i++) {
+ int i0 = i*4;
+ int i2 = i0 + 2;
+ float t = mtx[i0];
+ mtx[i0] = t*rcos + mtx[i2]*rsin;
+ mtx[i2] = mtx[i2]*rcos - t*rsin;
+ }
+
+ return mtx;
+ }
+
+ /**
+ * Multiply an existing 4x4 transformation matrix by a Z-axis
+ * rotation matrix quickly. This is much faster than calling
+ * setRotateZ() followed by multiply().
+ * Equiv. to: T = T*Rz
+ *
+ * Rz = 1 0 0 0
+ * 0 cos(a) sin(a) 0
+ * 0 -sin(a) cos(a) 0
+ * 0 0 0 1
+ *
+ * @param angle The rotation angle about the Y-axis in radians.
+ * @param mtx The 4x4 matrix to be multiplied by the rotation matrix.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] rotateZ(float angle, float mtx[]) {
+ float rsin = (float)Math.sin(angle);
+ float rcos = (float)Math.cos(angle);
+
+ for (int i = 0 ; i < 4 ; i++) {
+ int i0 = i*4;
+ int i1 = i0 + 1;
+ float t = mtx[i0];
+ mtx[i0] = t*rcos - mtx[i1]*rsin;
+ mtx[i1] = t*rsin + mtx[i1]*rcos;
+ }
+
+ return mtx;
+ }
+
+ /**
+ * Multiply an existing 4x4 transformation matrix by a set of
+ * scale factors quickly. This is much faster than calling
+ * setScale() followed by multiply().
+ * Equiv. to: T = T*S
+ *
+ * S = sx 0 0 0
+ * 0 sy 0 0
+ * 0 0 sz 0
+ * 0 0 0 1
+ *
+ * @param sx The scale factor in the X-axis direction.
+ * @param sy The scale factor in the Y-axis direction.
+ * @param sz The scale factor in the Z-axis direction.
+ * @param mtx The 4x4 matrix to be multiplied by the scale factor matrix.
+ * @param A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] scale(float sx, float sy, float sz, float mtx[]) {
+ for (int i = 0 ; i < 4 ; i++) {
+ int i0 = i*4;
+ mtx[i0] *= sx;
+ mtx[i0 + 1] *= sy;
+ mtx[i0 + 2] *= sz;
+ }
+
+ return mtx;
+ }
+
+ /**
+ * Multiply an existing 4x4 transformation matrix by a
+ * translation matrix quickly. This is much faster than calling
+ * setTranslate() followed by multiply().
+ * Equiv. to: T = T*Tr
+ *
+ * Tr = 1 0 0 Tx
+ * 0 1 0 Ty
+ * 0 0 1 Tz
+ * 0 0 0 1
+ *
+ * @param tx The translation amount in the X-axis direction.
+ * @param ty The translation amount in the Y-axis direction.
+ * @param tz The translation amount in the Z-axis direction.
+ * @param mtx The 4x4 matrix to be multiplied by the translation matrix.
+ * @return A reference to the output matrix "mtx" is returned.
+ **/
+ public static final float[] translate(float tx, float ty, float tz, float mtx[]) {
+ for (int i=0 ; i < 4 ; i++) {
+ int i0 = i*4;
+ int i3 = i0 + 3;
+ mtx[i0] += mtx[i3]*tx;
+ mtx[i0 + 1] += mtx[i3]*ty;
+ mtx[i0 + 2] += mtx[i3]*tz;
+ }
+
+ return mtx;
+ }
+
+}
|