Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.math;

import java.nio.FloatBuffer;

import com.badlogic.gdx.utils.BufferUtils;

public class Matrix4
{
        /* OpenGL Colum Major:
         *   m[0] m[4] m[8]  m[12]
         *   m[1] m[5] m[9]  m[13]
         *   m[2] m[6] m[10] m[14]
         *   m[3] m[7] m[11] m[15]
         */

       
        public static final int M11 = 0;
        public static final int M21 = 1;
        public static final int M31 = 2;
        public static final int M41 = 3;
        public static final int M12 = 4;
        public static final int M22 = 5;
        public static final int M32 = 6;
        public static final int M42 = 7;
        public static final int M13 = 8;
        public static final int M23 = 9;
        public static final int M33 = 10;
        public static final int M43 = 11;
        public static final int M14 = 12;
        public static final int M24 = 13;
        public static final int M34 = 14;
        public static final int M44 = 15;
       
/*      public float m11;
        public float m21;
        public float m31;
        public float m41;
        public float m12;
        public float m22;
        public float m32;
        public float m42;
        public float m13;
        public float m23;
        public float m33;
        public float m43;
        public float m14;
        public float m24;
        public float m34;
        public float m44;*/

       
        public static final int MATRIX_SIZE = 4;
       
        public float values[] = new float[MATRIX_SIZE*MATRIX_SIZE];
       
        public Matrix4()
        {
        }
       
        /** Copy constructor. */
        public Matrix4(Matrix4 b)
        {
                for (int i = 0; i < values.length; i++)
                        this.values[i] = b.values[i];
               
                /*this.m11 = b.m11; this.m21 = b.m21; this.m31 = b.m31; this.m41 = b.m41;
                this.m12 = b.m12; this.m22 = b.m22; this.m32 = b.m32; this.m42 = b.m42;
                this.m13 = b.m13; this.m23 = b.m23; this.m33 = b.m33; this.m43 = b.m43;
                this.m14 = b.m14; this.m24 = b.m24; this.m34 = b.m34; this.m44 = b.m44;*/

        }
       
        public Matrix4(float[] m)
        {
                //fromGLMatrix(m);
                for (int i = 0; i < values.length; i++)
                        this.values[i] = m[i];
        }
       
        public float get(int row, int col)
        {
                return values[col*MATRIX_SIZE + row];
               
/*              switch (row)
                {
                case 0:
                        switch (col)
                        {
                        case 0: return m11;
                        case 1: return m12;
                        case 2: return m13;
                        case 3: return m14;
                        }
                        break;
                case 1:
                        switch (col)
                        {
                        case 0: return m21;
                        case 1: return m22;
                        case 2: return m23;
                        case 3: return m24;
                        }
                        break;
                case 2:
                        switch (col)
                        {
                        case 0: return m31;
                        case 1: return m32;
                        case 2: return m33;
                        case 3: return m34;
                        }
                        break;
                case 3:
                        switch (col)
                        {
                        case 0: return m41;
                        case 1: return m42;
                        case 2: return m43;
                        case 3: return m44;
                        }
                        break;
                }
                // should never reach here -> TODO: assert
                return 0.0f;*/

        }
       
        public void set(int row, int col, float value)
        {
                values[col*MATRIX_SIZE + row] = value;
               
                /*switch (row)
                {
                case 0:
                        switch (col)
                        {
                        case 0:
                                m11 = value;
                                break;
                        case 1:
                                m12 = value;
                                break;
                        case 2:
                                m13 = value;
                                break;
                        case 3:
                                m14 = value;
                                break;
                        }
                        break;
                case 1:
                        switch (col)
                        {
                        case 0:
                                m21 = value;
                                break;
                        case 1:
                                m22 = value;
                                break;
                        case 2:
                                m23 = value;
                                break;
                        case 3:
                                m24 = value;
                                break;
                        }
                        break;
                case 2:
                        switch (col)
                        {
                        case 0:
                                m31 = value;
                                break;
                        case 1:
                                m32 = value;
                                break;
                        case 2:
                                m33 = value;
                                break;
                        case 3:
                                m34 = value;
                                break;
                        }
                        break;
                case 3:
                        switch (col)
                        {
                        case 0:
                                m41 = value;
                                break;
                        case 1:
                                m42 = value;
                                break;
                        case 2:
                                m43 = value;
                                break;
                        case 3:
                                m44 = value;
                                break;
                        }
                        break;
                }*/

        }
       
        public void zero()
        {
                for (int i = 0; i < values.length; i++)
                        values[i] = 0.0f;
                /*m11 = 0.0f; m12 = 0.0f; m13 = 0.0f; m14 = 0.0f;              
                m21 = 0.0f; m22 = 0.0f; m23 = 0.0f; m24 = 0.0f;
                m31 = 0.0f; m32 = 0.0f; m33 = 0.0f; m34 = 0.0f;
                m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 0.0f;*/

        }
       
        public void identity()
        {
                zero();
                //m11 = 1.0f; m22 = 1.0f; m33 = 1.0f; m44 = 1.0f;
                values[M11] = 1.0f; values[M22] = 1.0f; values[M33] = 1.0f; values[M44] = 1.0f;
        }
       
        public boolean equals(Matrix4 other)
        {
                for (int i = 0; i < values.length; i++)
                {
                        if (this.values[i] != other.values[i])
                                return false;
                }
                return true;
               
                /*return ((m11 == other.m11) && (m12 == other.m12) && (m13 == other.m13) && (m14 == other.m14) &&
                                (m21 == other.m21) && (m22 == other.m22) && (m23 == other.m23) && (m24 == other.m24) &&
                                (m31 == other.m31) && (m32 == other.m32) && (m33 == other.m33) && (m34 == other.m34) &&
                                (m41 == other.m41) && (m42 == other.m42) && (m43 == other.m43) && (m44 == other.m44));*/
               
        }
       
        public boolean isSingular()
    {
        float determinant = getDeterminant();
        return ((float)Math.abs(determinant) < MathUtil.EPSILON);
    }
       
        public Matrix4 getTranspose()
        {
                Matrix4 result = new Matrix4();
               
                for (int row = 0; row < MATRIX_SIZE; row++)
                {
                        for (int col = 0; col < MATRIX_SIZE; col++)
                        {
                                float v = this.get(row, col);
                                this.set(col, row, v);
                        }
                }
               
/*              result.m11 = m11;
                result.m12 = m21;
                result.m13 = m31;
                result.m14 = m41;
                result.m21 = m12;
                result.m22 = m22;
                result.m23 = m32;
                result.m24 = m42;
                result.m31 = m13;
                result.m32 = m23;
                result.m33 = m33;
                result.m34 = m43;
                result.m41 = m14;
                result.m42 = m24;
                result.m43 = m34;
                result.m44 = m44;*/

                return result;
        }
       
        public float getDeterminant()
        {
               
        float result =
                values[M14] * values[M23] * values[M32] * values[M41] -
                values[M13] * values[M24] * values[M32] * values[M41] -
                values[M14] * values[M22] * values[M33] * values[M41] +
                values[M12] * values[M24] * values[M33] * values[M41] +
                values[M13] * values[M22] * values[M34] * values[M41] -
                values[M12] * values[M23] * values[M34] * values[M41] -
                values[M14] * values[M23] * values[M31] * values[M42] +
                values[M13] * values[M24] * values[M31] * values[M42] +
                values[M14] * values[M21] * values[M33] * values[M42] -
                values[M11] * values[M24] * values[M33] * values[M42] -
                values[M13] * values[M21] * values[M34] * values[M42] +
                values[M11] * values[M23] * values[M34] * values[M42] +
                values[M14] * values[M22] * values[M31] * values[M43] -
                values[M12] * values[M24] * values[M31] * values[M43] -
                values[M14] * values[M21] * values[M32] * values[M43] +
                values[M11] * values[M24] * values[M32] * values[M43] +
                values[M12] * values[M21] * values[M34] * values[M43] -
                values[M11] * values[M22] * values[M34] * values[M43] -
                values[M13] * values[M22] * values[M31] * values[M44] +
                values[M12] * values[M23] * values[M31] * values[M44] +
                values[M13] * values[M21] * values[M32] * values[M44] -
                values[M11] * values[M23] * values[M32] * values[M44] -
                values[M12] * values[M21] * values[M33] * values[M44] +
                values[M11] * values[M22] * values[M33] * values[M44];
            return result;
               
/*        float result =
            m14 * m23 * m32 * m41 -
            m13 * m24 * m32 * m41 -
            m14 * m22 * m33 * m41 +
            m12 * m24 * m33 * m41 +
            m13 * m22 * m34 * m41 -
            m12 * m23 * m34 * m41 -
            m14 * m23 * m31 * m42 +
            m13 * m24 * m31 * m42 +
            m14 * m21 * m33 * m42 -
            m11 * m24 * m33 * m42 -
            m13 * m21 * m34 * m42 +
            m11 * m23 * m34 * m42 +
            m14 * m22 * m31 * m43 -
            m12 * m24 * m31 * m43 -
            m14 * m21 * m32 * m43 +
            m11 * m24 * m32 * m43 +
            m12 * m21 * m34 * m43 -
            m11 * m22 * m34 * m43 -
            m13 * m22 * m31 * m44 +
            m12 * m23 * m31 * m44 +
            m13 * m21 * m32 * m44 -
            m11 * m23 * m32 * m44 -
            m12 * m21 * m33 * m44 +
            m11 * m22 * m33 * m44;
        return result;*/

        }
       
        public Matrix4 getInverse()
        {
                Matrix4 result = new Matrix4();
               
                float determinant = getDeterminant();
                if (determinant == 0.0f)
                {
                        // singular matrix cannot be inverted
                        return this;
                }
               
        result.values[M11] = values[M23] * values[M34] * values[M42]
                        - values[M24] * values[M33] * values[M42]
                        + values[M24] * values[M32] * values[M43]
                        - values[M22] * values[M34] * values[M43]
                        - values[M23] * values[M32] * values[M44]
                        + values[M22] * values[M33] * values[M44];
                result.values[M12] = values[M14] * values[M33] * values[M42]
                        - values[M13] * values[M34] * values[M42]
                        - values[M14] * values[M32] * values[M43]
                        + values[M12] * values[M34] * values[M43]
                        + values[M13] * values[M32] * values[M44]
                        - values[M12] * values[M33] * values[M44];
                result.values[M13] = values[M13] * values[M24] * values[M42]
                        - values[M14] * values[M23] * values[M42]
                        + values[M14] * values[M22] * values[M43]
                        - values[M12] * values[M24] * values[M43]
                        - values[M13] * values[M22] * values[M44]
                        + values[M12] * values[M23] * values[M44];
                result.values[M14] = values[M14] * values[M23] * values[M32]
                        - values[M13] * values[M24] * values[M32]
                        - values[M14] * values[M22] * values[M33]
                        + values[M12] * values[M24] * values[M33]
                        + values[M13] * values[M22] * values[M34]
                        - values[M12] * values[M23] * values[M34];
                result.values[M21] = values[M24] * values[M33] * values[M41]
                        - values[M23] * values[M34] * values[M41]
                        - values[M24] * values[M31] * values[M43]
                        + values[M21] * values[M34] * values[M43]
                        + values[M23] * values[M31] * values[M44]
                        - values[M21] * values[M33] * values[M44];
                result.values[M22] = values[M13] * values[M34] * values[M41]
                        - values[M14] * values[M33] * values[M41]
                        + values[M14] * values[M31] * values[M43]
                        - values[M11] * values[M34] * values[M43]
                        - values[M13] * values[M31] * values[M44]
                        + values[M11] * values[M33] * values[M44];
                result.values[M23] = values[M14] * values[M23] * values[M41]
                        - values[M13] * values[M24] * values[M41]
                        - values[M14] * values[M21] * values[M43]
                        + values[M11] * values[M24] * values[M43]
                        + values[M13] * values[M21] * values[M44]
                        - values[M11] * values[M23] * values[M44];
                result.values[M24] = values[M13] * values[M24] * values[M31]
                        - values[M14] * values[M23] * values[M31]
                        + values[M14] * values[M21] * values[M33]
                        - values[M11] * values[M24] * values[M33]
                        - values[M13] * values[M21] * values[M34]
                        + values[M11] * values[M23] * values[M34];
                result.values[M31] = values[M22] * values[M34] * values[M41]
                        - values[M24] * values[M32] * values[M41]
                        + values[M24] * values[M31] * values[M42]
                        - values[M21] * values[M34] * values[M42]
                        - values[M22] * values[M31] * values[M44]
                        + values[M21] * values[M32] * values[M44];
                result.values[M32] = values[M14] * values[M32] * values[M41]
                        - values[M12] * values[M34] * values[M41]
                        - values[M14] * values[M31] * values[M42]
                        + values[M11] * values[M34] * values[M42]
                        + values[M12] * values[M31] * values[M44]
                        - values[M11] * values[M32] * values[M44];
                result.values[M33] = values[M12] * values[M24] * values[M41]
                        - values[M14] * values[M22] * values[M41]
                        + values[M14] * values[M21] * values[M42]
                        - values[M11] * values[M24] * values[M42]
                        - values[M12] * values[M21] * values[M44]
                        + values[M11] * values[M22] * values[M44];
                result.values[M34] = values[M14] * values[M22] * values[M31]
                        - values[M12] * values[M24] * values[M31]
                        - values[M14] * values[M21] * values[M32]
                        + values[M11] * values[M24] * values[M32]
                        + values[M12] * values[M21] * values[M34]
                        - values[M11] * values[M22] * values[M34];
                result.values[M41] = values[M23] * values[M32] * values[M41]
                        - values[M22] * values[M33] * values[M41]
                        - values[M23] * values[M31] * values[M42]
                        + values[M21] * values[M33] * values[M42]
                        + values[M22] * values[M31] * values[M43]
                        - values[M21] * values[M32] * values[M43];
                result.values[M42] = values[M12] * values[M33] * values[M41]
                        - values[M13] * values[M32] * values[M41]
                        + values[M13] * values[M31] * values[M42]
                        - values[M11] * values[M33] * values[M42]
                        - values[M12] * values[M31] * values[M43]
                        + values[M11] * values[M32] * values[M43];
                result.values[M43] = values[M13] * values[M22] * values[M41]
                        - values[M12] * values[M23] * values[M41]
                        - values[M13] * values[M21] * values[M42]
                        + values[M11] * values[M23] * values[M42]
                        + values[M12] * values[M21] * values[M43]
                        - values[M11] * values[M22] * values[M43];
                result.values[M44] = values[M12] * values[M23] * values[M31]
                        - values[M13] * values[M22] * values[M31]
                        + values[M13] * values[M21] * values[M32]
                        - values[M11] * values[M23] * values[M32]
                        - values[M12] * values[M21] * values[M33]
                        + values[M11] * values[M22] * values[M33];

   /*     result.m11 = m23 * m34 * m42
                                 - m24 * m33 * m42
                                 + m24 * m32 * m43
                                 - m22 * m34 * m43
                                 - m23 * m32 * m44
                                 + m22 * m33 * m44;
        result.m12 = m14 * m33 * m42
                                 - m13 * m34 * m42
                                 - m14 * m32 * m43
                                 + m12 * m34 * m43
                                 + m13 * m32 * m44
                                 - m12 * m33 * m44;
        result.m13 = m13 * m24 * m42
                                 - m14 * m23 * m42
                                 + m14 * m22 * m43
                                 - m12 * m24 * m43
                                 - m13 * m22 * m44
                                 + m12 * m23 * m44;
        result.m14 = m14 * m23 * m32
                                 - m13 * m24 * m32
                                 - m14 * m22 * m33
                                 + m12 * m24 * m33
                                 + m13 * m22 * m34
                                 - m12 * m23 * m34;
        result.m21 = m24 * m33 * m41
                                 - m23 * m34 * m41
                                 - m24 * m31 * m43
                                 + m21 * m34 * m43
                                 + m23 * m31 * m44
                                 - m21 * m33 * m44;
        result.m22 = m13 * m34 * m41
                                 - m14 * m33 * m41
                                 + m14 * m31 * m43
                                 - m11 * m34 * m43
                                 - m13 * m31 * m44
                                 + m11 * m33 * m44;
        result.m23 = m14 * m23 * m41
                                 - m13 * m24 * m41
                                 - m14 * m21 * m43
                                 + m11 * m24 * m43
                                 + m13 * m21 * m44
                                 - m11 * m23 * m44;
        result.m24 = m13 * m24 * m31
                                 - m14 * m23 * m31
                                 + m14 * m21 * m33
                                 - m11 * m24 * m33
                                 - m13 * m21 * m34
                                 + m11 * m23 * m34;
        result.m31 = m22 * m34 * m41
                                 - m24 * m32 * m41
                                 + m24 * m31 * m42
                                 - m21 * m34 * m42
                                 - m22 * m31 * m44
                                 + m21 * m32 * m44;
        result.m32 = m14 * m32 * m41
                                 - m12 * m34 * m41
                                 - m14 * m31 * m42
                                 + m11 * m34 * m42
                                 + m12 * m31 * m44
                                 - m11 * m32 * m44;
        result.m33 = m12 * m24 * m41
                                 - m14 * m22 * m41
                                 + m14 * m21 * m42
                                 - m11 * m24 * m42
                                 - m12 * m21 * m44
                                 + m11 * m22 * m44;
        result.m34 = m14 * m22 * m31
                                 - m12 * m24 * m31
                                 - m14 * m21 * m32
                                 + m11 * m24 * m32
                                 + m12 * m21 * m34
                                 - m11 * m22 * m34;
        result.m41 = m23 * m32 * m41
                                 - m22 * m33 * m41
                                 - m23 * m31 * m42
                                 + m21 * m33 * m42
                                 + m22 * m31 * m43
                                 - m21 * m32 * m43;
        result.m42 = m12 * m33 * m41
                                 - m13 * m32 * m41
                                 + m13 * m31 * m42
                                 - m11 * m33 * m42
                                 - m12 * m31 * m43
                                 + m11 * m32 * m43;
        result.m43 = m13 * m22 * m41
                                 - m12 * m23 * m41
                                 - m13 * m21 * m42
                                 + m11 * m23 * m42
                                 + m12 * m21 * m43
                                 - m11 * m22 * m43;
        result.m44 = m12 * m23 * m31
                                 - m13 * m22 * m31
                                 + m13 * m21 * m32
                                 - m11 * m23 * m32
                                 - m12 * m21 * m33
                                 + m11 * m22 * m33;*/


                float multiply = 1.0f / determinant;
               
                for (int i = 0; i < values.length; i++)
                        result.values[i] *= multiply;
               
/*              result.m11 *= multiply;
                result.m21 *= multiply;
                result.m31 *= multiply;
                result.m41 *= multiply;
                result.m12 *= multiply;
                result.m22 *= multiply;
                result.m32 *= multiply;
                result.m42 *= multiply;
                result.m13 *= multiply;
                result.m23 *= multiply;
                result.m33 *= multiply;
                result.m43 *= multiply;
                result.m14 *= multiply;
                result.m24 *= multiply;
                result.m34 *= multiply;
                result.m44 *= multiply;*/


                return result;
        }

        public void copyTo(Matrix4 target)
        {
                for (int i = 0; i < values.length; i++)
                        target.values[i] = this.values[i];
                /*target.m11 = m11; target.m12 = m12; target.m13 = m13; target.m14 = m14;
                target.m21 = m21; target.m22 = m22; target.m23 = m23; target.m24 = m24;
                target.m31 = m31; target.m32 = m32; target.m33 = m33; target.m34 = m34;
                target.m41 = m41; target.m42 = m42; target.m43 = m43; target.m44 = m44;*/

        }
       
        public void copyFrom(Matrix4 source)
        {
                for (int i = 0; i < values.length; i++)
                        this.values[i] = source.values[i];
                /*m11 = source.m11; m12 = source.m12; m13 = source.m13; m14 = source.m14;
                m21 = source.m21; m22 = source.m22; m23 = source.m23; m24 = source.m24;
                m31 = source.m31; m32 = source.m32; m33 = source.m33; m34 = source.m34;
                m41 = source.m41; m42 = source.m42; m43 = source.m43; m44 = source.m44;*/

        }
       
        public void postMultiply(Matrix4 v)
        {
                multiply(this, this, v);
        }
       
        public void preMultiply(Matrix4 v)
        {
                multiply(this, v, this);
        }
       
        static public void multiply(Matrix4 result, Matrix4 a, Matrix4 b)
        {
        float result11 = a.values[M11] * b.values[M11] + a.values[M21] * b.values[M12] + a.values[M31] * b.values[M13] + a.values[M41] * b.values[M14];
        float result21 = a.values[M11] * b.values[M21] + a.values[M21] * b.values[M22] + a.values[M31] * b.values[M23] + a.values[M41] * b.values[M24];
        float result31 = a.values[M11] * b.values[M31] + a.values[M21] * b.values[M32] + a.values[M31] * b.values[M33] + a.values[M41] * b.values[M34];
        float result41 = a.values[M11] * b.values[M41] + a.values[M21] * b.values[M42] + a.values[M31] * b.values[M43] + a.values[M41] * b.values[M44];
        float result12 = a.values[M12] * b.values[M11] + a.values[M22] * b.values[M12] + a.values[M32] * b.values[M13] + a.values[M42] * b.values[M14];
        float result22 = a.values[M12] * b.values[M21] + a.values[M22] * b.values[M22] + a.values[M32] * b.values[M23] + a.values[M42] * b.values[M24];
        float result32 = a.values[M12] * b.values[M31] + a.values[M22] * b.values[M32] + a.values[M32] * b.values[M33] + a.values[M42] * b.values[M34];
        float result42 = a.values[M12] * b.values[M41] + a.values[M22] * b.values[M42] + a.values[M32] * b.values[M43] + a.values[M42] * b.values[M44];
        float result13 = a.values[M13] * b.values[M11] + a.values[M23] * b.values[M12] + a.values[M33] * b.values[M13] + a.values[M43] * b.values[M14];
        float result23 = a.values[M13] * b.values[M21] + a.values[M23] * b.values[M22] + a.values[M33] * b.values[M23] + a.values[M43] * b.values[M24];
                float result33 = a.values[M13] * b.values[M31] + a.values[M23] * b.values[M32] + a.values[M33] * b.values[M33] + a.values[M43] * b.values[M34];
                float result43 = a.values[M13] * b.values[M41] + a.values[M23] * b.values[M42] + a.values[M33] * b.values[M43] + a.values[M43] * b.values[M44];
                float result14 = a.values[M14] * b.values[M11] + a.values[M24] * b.values[M12] + a.values[M34] * b.values[M13] + a.values[M44] * b.values[M14];
                float result24 = a.values[M14] * b.values[M21] + a.values[M24] * b.values[M22] + a.values[M34] * b.values[M23] + a.values[M44] * b.values[M24];
                float result34 = a.values[M14] * b.values[M31] + a.values[M24] * b.values[M32] + a.values[M34] * b.values[M33] + a.values[M44] * b.values[M34];
                float result44 = a.values[M14] * b.values[M41] + a.values[M24] * b.values[M42] + a.values[M34] * b.values[M43] + a.values[M44] * b.values[M44];
                result.values[M11] = result11;
                result.values[M21] = result21;
                result.values[M31] = result31;
                result.values[M41] = result41;
                result.values[M12] = result12;
                result.values[M22] = result22;
                result.values[M32] = result32;
                result.values[M42] = result42;
                result.values[M13] = result13;
                result.values[M23] = result23;
                result.values[M33] = result33;
                result.values[M43] = result43;
                result.values[M14] = result14;
                result.values[M24] = result24;
                result.values[M34] = result34;
                result.values[M44] = result44;
        }
       
        static public Matrix4 multiply(Matrix4 a, Matrix4 b)
        {
                Matrix4 result = new Matrix4();
                multiply(result, a, b);
                return result;
        }
       
        public void multiply(Matrix4 other)
        {
                Matrix4.multiply(this, this, other);
        }
       
        static public Matrix4 createIdentity()
        {
                return createScale(1.0f, 1.0f, 1.0f);
        }
       
        static public Matrix4 createScale(float sx, float sy, float sz)
        {
                Matrix4 result = new Matrix4();
                result.setScale(sx, sy, sz);
                return result;         
        }
       
        static public Matrix4 createScale(Vector3 scale)
        {
                return createScale(scale.x, scale.y, scale.z);
        }
       
        static public Matrix4 createScale(float s)
        {
                return createScale(s, s, s);
        }
       
        public void setScale(float sx, float sy, float sz)
        {
                zero();
                this.values[M11] = sx;
                this.values[M22] = sy;
                this.values[M33] = sz;
                this.values[M44] = 1.0f;
        }
       
        public void setScale(Vector3 scale)
        {
                setScale(scale.x, scale.y, scale.z);
        }
       
        public void setScale(float s)
        {
                setScale(s, s, s);
        }
       
        static public Matrix4 createRotationX(float degrees)
        {
        Matrix4 matrix = new Matrix4();
        matrix.setRotationX(degrees);
        return matrix;
        }
       
        public void setRotationX(float degrees)
        {
                float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

                this.identity();
        this.values[M22] = cosvalue;
        this.values[M32] = -sinvalue;
        this.values[M23] = sinvalue;
        this.values[M33] = cosvalue;
        }
       
        static public Matrix4 createRotationY(float degrees)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setRotationY(degrees);
        return matrix;
        }
       
        public void setRotationY(float degrees)
        {
        float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

        this.identity();
        this.values[M11] = cosvalue;
        this.values[M31] = sinvalue;
        this.values[M13] = -sinvalue;
        this.values[M33] = cosvalue;
        }
       
        static public Matrix4 createRotationZ(float degrees)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setRotationZ(degrees);
        return matrix;
        }
       
        public void setRotationZ(float degrees)
        {
        float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

        this.identity();
        this.values[M11] = cosvalue;
        this.values[M21] = -sinvalue;
        this.values[M12] = sinvalue;
        this.values[M22] = cosvalue;
        }
       
        static public Matrix4 createRotation(Vector3 axis, float degrees)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setRotation(axis, degrees);
        return matrix;
        }
       
        public void setRotation(Vector3 axis, float degrees)
        {
        float radangle = MathUtil.degToRad(degrees);
        float radcos = (float)Math.cos(radangle);
        float radsin = (float)Math.sin(radangle);

        this.identity();
        this.values[M11] = radcos + axis.x * axis.x * (1 - radcos);
        this.values[M21] = axis.z * radsin + axis.y * axis.x * (1 - radcos);
        this.values[M31] = -axis.y * radsin + axis.z * axis.x * (1 - radcos);
        this.values[M12] = -axis.z * radsin + axis.x * axis.y * (1 - radcos);
        this.values[M22] = radcos + axis.y * axis.y * (1 - radcos);
        this.values[M32] = axis.x * radsin + axis.z * axis.y * (1 - radcos);
        this.values[M13] = axis.y * radsin + axis.x * axis.z * (1 - radcos);
        this.values[M23] = -axis.x * radsin + axis.y * axis.z * (1 - radcos);
        this.values[M33] = radcos + axis.z * axis.z * (1 - radcos);
        this.values[M44] = 1.0f;
        }
       
        static public Matrix4 createTranslation(float x, float y, float z)
        {
                Matrix4 result = new Matrix4();
                result.setTranslation(x, y, z);
        return result;
        }
       
        static public Matrix4 createTranslation(Vector3 translate)
        {
                return createTranslation(translate.x, translate.y, translate.z);
        }
       
        public void setTranslation(float x, float y, float z)
        {              
        /*result.m11 = 1.0f; result.m21 = 0.0f; result.m31 = 0.0f; result.m41 = x;
        result.m12 = 0.0f; result.m22 = 1.0f; result.m32 = 0.0f; result.m42 = y;
        result.m13 = 0.0f; result.m23 = 0.0f; result.m33 = 1.0f; result.m43 = z;
        result.m14 = 0.0f; result.m24 = 0.0f; result.m34 = 0.0f; result.m44 = 1.0f;*/

                this.values[M11] = 1.0f; this.values[M21] = 0.0f; this.values[M31] = 0.0f; this.values[M41] = 0.0f;
                this.values[M12] = 0.0f; this.values[M22] = 1.0f; this.values[M32] = 0.0f; this.values[M42] = 0.0f;
                this.values[M13] = 0.0f; this.values[M23] = 0.0f; this.values[M33] = 1.0f; this.values[M43] = 0.0f;
                this.values[M14] = x;    this.values[M24] = y;    this.values[M34] = z;    this.values[M44] = 1.0f;
                /*this.values[M11] = 1.0f; this.values[M21] = 0.0f; this.values[M31] = 0.0f; this.values[M41] = x;
                this.values[M12] = 0.0f; this.values[M22] = 1.0f; this.values[M32] = 0.0f; this.values[M42] = y;
                this.values[M13] = 0.0f; this.values[M23] = 0.0f; this.values[M33] = 1.0f; this.values[M43] = z;
                this.values[M14] = 0;    this.values[M24] = 0;    this.values[M34] = 0;    this.values[M44] = 1.0f;*/

        }
       
        public void setTranslation(Vector3 translate)
        {
                setTranslation(translate.x, translate.y, translate.z);
        }
       
        static public Matrix4 createFromVectors(Vector3 forward, Vector3 up, Vector3 right)
        {
        forward.normalize();
        up.normalize();
        right.normalize();
       
        Matrix4 result = new Matrix4();
        result.setFromVectors(forward, up, right);        
        return result;
        }
       
        public void setFromVectors(Vector3 forward, Vector3 up, Vector3 right)
        {
        forward.normalize();
        up.normalize();
        right.normalize();
       
        identity();
       
        this.values[M11] = right.x;
        this.values[M12] = right.y;
        this.values[M13] = right.z;
        this.values[M21] = up.x;
        this.values[M22] = up.y;
        this.values[M23] = up.z;
        this.values[M31] = -forward.x;
        this.values[M32] = -forward.y;
        this.values[M33] = -forward.z;
        this.values[M44] = 1.0f;
        }
       
        static public Matrix4 createPerspective(float fovDegreesY, float aspect, float zNear, float zFar)
        {
                Matrix4 result = new Matrix4();
                result.setPerspective(fovDegreesY, aspect, zNear, zFar);
                return result;
        }
       
        public void setPerspective(float fovDegreesY, float aspect, float zNear, float zFar)
        {
        float f = 1.0f / (float) Math.tan(fovDegreesY * (Math.PI / 360.0));
        float rangeReciprocal = 1.0f / (zNear - zFar);
               
                this.values[M11] = f / aspect;
                this.values[M21] = 0.0f;
                this.values[M31] = 0.0f;
                this.values[M41] = 0.0f;
               
                this.values[M12] = 0.0f;
                this.values[M22] = f;
                this.values[M32] = 0.0f;
                this.values[M42] = 0.0f;
               
                this.values[M13] = 0.0f;
                this.values[M23] = 0.0f;
                this.values[M33] = (zFar + zNear) * rangeReciprocal;
                this.values[M43] = -1.0f;
               
                this.values[M14] = 0.0f;
                this.values[M24] = 0.0f;
                this.values[M34] = 2.0f * zFar * zNear * rangeReciprocal;
                this.values[M44] = 0.0f;
        }
       
        static public Matrix4 createFrustum(float left, float right, float bottom, float top, float near, float far)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setFrustum(left, right, bottom, top, near, far);
                return matrix;
        }
       
        public void setFrustum(float left, float right, float bottom, float top, float near, float far)
        {
        if (left == right)
        {
            throw new IllegalArgumentException("left == right");
        }
        if (top == bottom)
        {
            throw new IllegalArgumentException("top == bottom");
        }
        if (near == far)
        {
            throw new IllegalArgumentException("near == far");
        }
        if (near <= 0.0f)
        {
            throw new IllegalArgumentException("near <= 0.0f");
        }
        if (far <= 0.0f)
        {
            throw new IllegalArgumentException("far <= 0.0f");
        }
       
        final float r_width  = 1.0f / (right - left);
        final float r_height = 1.0f / (top - bottom);
        final float r_depth  = 1.0f / (near - far);
        final float x = 2.0f * (near * r_width);
        final float y = 2.0f * (near * r_height);
        final float A = 2.0f * ((right + left) * r_width);
        final float B = (top + bottom) * r_height;
        final float C = (far + near) * r_depth;
        final float D = 2.0f * (far * near * r_depth);
       
        this.values[M11] = x;
        this.values[M21] = 0.0f;
        this.values[M31] = 0.0f;
        this.values[M41] = 0.0f;
       
        this.values[M12] = 0.0f;
        this.values[M22] = y;
        this.values[M32] = 0.0f;
        this.values[M42] = 0.0f;
       
        this.values[M13] = A;
        this.values[M23] = B;
        this.values[M33] = C;
        this.values[M43] = -1.0f;
       
        this.values[M14] = 0.0f;
        this.values[M24] = 0.0f;
        this.values[M34] = D;
        this.values[M44] = 0.0f;
        }

        static public Matrix4 createOrtho(float left, float right, float bottom, float top, float near, float far)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setOrtho(left, right, bottom, top, near, far);
                return matrix;
        }
       
        public void setOrtho(float left, float right, float bottom, float top, float near, float far)
        {
                if (left == right)
                        throw new IllegalArgumentException("left and right must not be identical!");
               
                if (bottom == top)
                        throw new IllegalArgumentException("bottom and top must not be identical!");
               
                if (near == far)
                        throw new IllegalArgumentException("near and far must not be identical!");
               
                final float r_width  = 1.0f / (right - left);
                final float r_height = 1.0f / (top - bottom);
                final float r_depth  = 1.0f / (far - near);
                final float x =  2.0f * (r_width);
                final float y =  2.0f * (r_height);
                final float z = -2.0f * (r_depth);
                final float tx = -(right + left) * r_width;
                final float ty = -(top + bottom) * r_height;
                final float tz = -(far + near) * r_depth;
               
               
/*              m[mOffset + 0] = x;
                m[mOffset + 5] = y;
                m[mOffset +10] = z;
                m[mOffset +12] = tx;
                m[mOffset +13] = ty;
                m[mOffset +14] = tz;
                m[mOffset +15] = 1.0f;
                m[mOffset + 1] = 0.0f;
                m[mOffset + 2] = 0.0f;
                m[mOffset + 3] = 0.0f;
                m[mOffset + 4] = 0.0f;
                m[mOffset + 6] = 0.0f;
                m[mOffset + 7] = 0.0f;
                m[mOffset + 8] = 0.0f;
                m[mOffset + 9] = 0.0f;
                m[mOffset + 11] = 0.0f;*/


                this.values[M11] = x;           this.values[M21] = 0.0f;        this.values[M31] = 0.0f;        this.values[M41] = 0.0f;
                this.values[M12] = 0.0f;        this.values[M22] = y;           this.values[M32] = 0.0f;        this.values[M42] = 0.0f;
                this.values[M13] = 0.0f;        this.values[M23] = 0.0f;        this.values[M33] = z;           this.values[M43] = 0.0f;
                this.values[M14] = tx;          this.values[M24] = ty;          this.values[M34] = tz;          this.values[M44] = 1.0f;
        }              
        /*      m[0] = m11; m[1] = m21; m[2] = m31; m[3] = m41;
                m[4] = m12; m[5] = m22; m[6] = m32; m[7] = m42;
                m[8] = m13; m[9] = m23; m[10] = m33; m[11] = m43;
                m[12] = m14; m[13] = m24; m[14] = m34; m[15] = m44;*/


        static public Matrix4 createLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
        {
                Matrix4 matrix = new Matrix4();
                matrix.setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
                return matrix;
        }
       
        public void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
        {
        float fx = centerX - eyeX;
        float fy = centerY - eyeY;
        float fz = centerZ - eyeZ;

        // Normalize f
        float rlf = 1.0f / Vector3.length(fx, fy, fz);
        fx *= rlf;
        fy *= rlf;
        fz *= rlf;

        // compute s = f x up (x means "cross product")
        float sx = fy * upZ - fz * upY;
        float sy = fz * upX - fx * upZ;
        float sz = fx * upY - fy * upX;

        // and normalize s
        float rls = 1.0f / Vector3.length(sx, sy, sz);
        sx *= rls;
        sy *= rls;
        sz *= rls;

        // compute u = s x f
        float ux = sy * fz - sz * fy;
        float uy = sz * fx - sx * fz;
        float uz = sx * fy - sy * fx;
       
        this.values[M11] = sx;
        this.values[M21] = ux;
        this.values[M31] = -fx;
        this.values[M41] = 0.0f;

        this.values[M12] = sy;
        this.values[M22] = uy;
        this.values[M32] = -fy;
        this.values[M42] = 0.0f;

        this.values[M13] = sz;
        this.values[M23] = uz;
        this.values[M33] = -fz;
        this.values[M43] = 0.0f;

        this.values[M14] = 0.0f;
        this.values[M24] = 0.0f;
        this.values[M34] = 0.0f;
        this.values[M44] = 1.0f;
       
        this.values[M14] = this.values[M11] * -eyeX + this.values[M12] * -eyeY + this.values[M13] * -eyeZ + this.values[M14];
        this.values[M24] = this.values[M21] * -eyeX + this.values[M22] * -eyeY + this.values[M23] * -eyeZ + this.values[M24];
        this.values[M34] = this.values[M31] * -eyeX + this.values[M32] * -eyeY + this.values[M33] * -eyeZ + this.values[M34];
        this.values[M44] = this.values[M41] * -eyeX + this.values[M42] * -eyeY + this.values[M43] * -eyeZ + this.values[M44];
        }
       
        public Vector3 transform(Vector3 vector)
        {
        return new Vector3(
                values[M11] * vector.x + values[M12] * vector.y + values[M13] * vector.z,
                values[M21] * vector.x + values[M22] * vector.y + values[M32] * vector.z,
                values[M31] * vector.x + values[M32] * vector.y + values[M33] * vector.z);
               
                /*return new Vector3(
                values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41],
                values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42],
                values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43]);*/

        }
       
        public Vector4 transform(Vector4 vector)
        {
        return new Vector4(
                values[M11] * vector.x + values[M12] * vector.y + values[M13] * vector.z + values[M14] * vector.w,
                values[M21] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M24] * vector.w,
                values[M31] * vector.x + values[M32] * vector.y + values[M33] * vector.z + values[M34] * vector.w,
                values[M41] * vector.x + values[M42] * vector.y + values[M43] * vector.z + values[M44] * vector.w);
       
/*        return new Vector4(
                values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41] * vector.w,
                values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42] * vector.w,
                values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43] * vector.w,
                values[M14] * vector.x + values[M24] * vector.y + values[M34] * vector.z + values[M44] * vector.w);*/

        }
       
        public Vector4 homogenousTransform(Vector4 vector)
        {
        Vector4 result = transform(vector);
        result.x /= result.w;
        result.y /= result.w;
        result.z /= result.w;
        result.w /= result.w;
        return result;
        }
       
        static public void interpolate(Matrix4 result, Matrix4 a, Matrix4 b, float ratio)
        {
        result.values[M11] = a.values[M11] + (b.values[M11] - a.values[M11]) * ratio;
        result.values[M21] = a.values[M21] + (b.values[M21] - a.values[M21]) * ratio;
        result.values[M31] = a.values[M31] + (b.values[M31] - a.values[M31]) * ratio;
        result.values[M41] = a.values[M41] + (b.values[M41] - a.values[M41]) * ratio;
        result.values[M12] = a.values[M12] + (b.values[M12] - a.values[M12]) * ratio;
        result.values[M22] = a.values[M22] + (b.values[M22] - a.values[M22]) * ratio;
        result.values[M32] = a.values[M32] + (b.values[M32] - a.values[M32]) * ratio;
        result.values[M42] = a.values[M42] + (b.values[M42] - a.values[M42]) * ratio;
        result.values[M13] = a.values[M13] + (b.values[M13] - a.values[M13]) * ratio;
        result.values[M23] = a.values[M23] + (b.values[M23] - a.values[M23]) * ratio;
        result.values[M33] = a.values[M33] + (b.values[M33] - a.values[M33]) * ratio;
        result.values[M43] = a.values[M43] + (b.values[M43] - a.values[M43]) * ratio;
        result.values[M14] = a.values[M14] + (b.values[M14] - a.values[M14]) * ratio;
        result.values[M24] = a.values[M24] + (b.values[M24] - a.values[M24]) * ratio;
        result.values[M34] = a.values[M34] + (b.values[M34] - a.values[M34]) * ratio;
        result.values[M44] = a.values[M44] + (b.values[M44] - a.values[M44]) * ratio;
        }
       
        static public Matrix4 interpolate(Matrix4 a, Matrix4 b, float ratio)
        {
                Matrix4 result = createIdentity();
                interpolate(result, a, b, ratio);
                return result;
        }
       
        public Vector3 getForwardVector()
        {
                Vector3 forward = new Vector3(-values[M31], -values[M32], -values[M33]);
        forward.normalize();
        return forward;
        }
       
        public Vector3 getUpVector()
        {
        Vector3 up = new Vector3(values[M21], values[M22], values[M23]);
        up.normalize();
        return up;
        }
       
        public Vector3 getRightVector()
        {
        Vector3 right = new Vector3(values[M11], values[M12], values[M13]);
        right.normalize();
        return right;
        }
       
        public float[] toGLMatrix()
        {
                return values;
                /*float[] m = new float[16];
               
                m[0] = m11; m[1] = m21; m[2] = m31; m[3] = m41;
                m[4] = m12; m[5] = m22; m[6] = m32; m[7] = m42;
                m[8] = m13; m[9] = m23; m[10] = m33; m[11] = m43;
                m[12] = m14; m[13] = m24; m[14] = m34; m[15] = m44;
               
                return m;*/

        }
       
        public void fromGLMatrix(float[] m)
        {
                values = m;
                /*m11 = m[0]; m21 = m[1]; m31 = m[2]; m41 = m[3];
                m12 = m[4]; m22 = m[5]; m32 = m[6]; m42 = m[7];
                m13 = m[8]; m23 = m[9]; m33 = m[10]; m43 = m[11];
                m14 = m[12]; m24 = m[13]; m34 = m[14]; m44 = m[15];*/

        }      
       
        public FloatBuffer toFloatBuffer()
        {
                FloatBuffer buffer = BufferUtils.newFloatBuffer(16);
               
                BufferUtils.copy(values, buffer, values.length, 0);
               
/*              buffer.put(m11); buffer.put(m21); buffer.put(m31); buffer.put(m41);
                buffer.put(m12); buffer.put(m22); buffer.put(m32); buffer.put(m42);
                buffer.put(m13); buffer.put(m23); buffer.put(m33); buffer.put(m43);
                buffer.put(m14); buffer.put(m24); buffer.put(m34); buffer.put(m44);*/

               
                return buffer;
        }
}