Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.Bauzoid.math;

public class Matrix3
{
/* OpenGL Colum Major:
 *   m[0] m[3] m[6]
 *   m[1] m[4] m[7]
 *   m[2] m[5] m[8]
 */

       
        public float m11;
        public float m21;
        public float m31;
        public float m12;
        public float m22;
        public float m32;
        public float m13;
        public float m23;
        public float m33;      
       
        static public final int MATRIX_SIZE = 3;
       
        public Matrix3()
        {
        }
       
        public float get(int row, int col)
        {
                switch (row)
                {
                case 0:
                        switch (col)
                        {
                        case 0: return m11;
                        case 1: return m12;
                        case 2: return m13;
                        }
                        break;
                case 1:
                        switch (col)
                        {
                        case 0: return m21;
                        case 1: return m22;
                        case 2: return m23;
                        }
                        break;
                case 2:
                        switch (col)
                        {
                        case 0: return m31;
                        case 1: return m32;
                        case 2: return m33;
                        }
                        break;
                }
                // should never reach here -> TODO: assert
                return 0.0f;
        }
       
        public void set(int row, int col, float value)
        {
                switch (row)
                {
                case 0:
                        switch (col)
                        {
                        case 0:
                                m11 = value;
                                break;
                        case 1:
                                m12 = value;
                                break;
                        case 2:
                                m13 = value;
                                break;
                        }
                        break;
                case 1:
                        switch (col)
                        {
                        case 0:
                                m21 = value;
                                break;
                        case 1:
                                m22 = value;
                                break;
                        case 2:
                                m23 = value;
                                break;
                        }
                        break;
                case 2:
                        switch (col)
                        {
                        case 0:
                                m31 = value;
                                break;
                        case 1:
                                m32 = value;
                                break;
                        case 2:
                                m33 = value;
                                break;
                        }
                        break;
                }
        }
       
        public void zero()
        {
                m11 = 0.0f; m12 = 0.0f; m13 = 0.0f;
                m21 = 0.0f; m22 = 0.0f; m23 = 0.0f;
                m31 = 0.0f; m32 = 0.0f; m33 = 0.0f;
        }
       
        public void identity()
        {
                zero();
                m11 = 1.0f; m22 = 1.0f; m33 = 1.0f;
        }
       
        public boolean equals(Matrix3 other)
        {
                return ((m11 == other.m11) && (m12 == other.m12) && (m13 == other.m13) &&
                                (m21 == other.m21) && (m22 == other.m22) && (m23 == other.m23) &&
                                (m31 == other.m31) && (m32 == other.m32) && (m33 == other.m33));               
        }
       
        public boolean isSingular()
    {
        float determinant = getDeterminant();
        return ((float)Math.abs(determinant) < MathUtil.EPSILON);
    }
       
        public Matrix3 getTranspose()
        {
                Matrix3 result = new Matrix3();
                result.m11 = m11;
                result.m12 = m21;
                result.m13 = m31;
                result.m21 = m12;
                result.m22 = m22;
                result.m23 = m32;
                result.m31 = m13;
                result.m32 = m23;
                result.m33 = m33;
                return result;
        }
       
        public float getDeterminant()
        {
        float result =
            m11 * (m22 * m33 - m23 * m32) -
            m21 * (m12 * m33 - m13 * m32) +
            m31 * (m12 * m23 - m13 * m22);
                return result;
        }
       
        public Matrix3 getInverse()
        {
                Matrix3 result = new Matrix3();
               
                float determinant = getDeterminant();
                if (determinant == 0.0f)
                {
                        // singular matrix cannot be inverted
                        return this;
                }

                result.m11 = m22 * m33 - m32 * m23;
                result.m21 = -(m21 * m33 - m23 * m31);
                result.m31 = m21 * m32 - m22 * m31;
                result.m12 = -(m12 * m33 - m32 * m13);
                result.m22 = m11 * m33 - m13 * m31;
                result.m32 = -(m11 * m32 - m12 * m31);
                result.m13 = m12 * m23 - m13 * m22;
                result.m23 = -(m11 * m23 - m13 * m21);
                result.m33 = m11 * m22 - m21 * m12;
               
                float multiply = 1.0f / determinant;
                result.m11 *= multiply;
                result.m21 *= multiply;
                result.m31 *= multiply;
                result.m12 *= multiply;
                result.m22 *= multiply;
                result.m32 *= multiply;
                result.m13 *= multiply;
                result.m23 *= multiply;
                result.m33 *= multiply;

                return result;
        }

        public void copyTo(Matrix3 target)
        {
                target.m11 = m11; target.m12 = m12; target.m13 = m13;
                target.m21 = m21; target.m22 = m22; target.m23 = m23;
                target.m31 = m31; target.m32 = m32; target.m33 = m33;
        }
       
        public void copyFrom(Matrix3 source)
        {
                m11 = source.m11; m12 = source.m12; m13 = source.m13;
                m21 = source.m21; m22 = source.m22; m23 = source.m23;
                m31 = source.m31; m32 = source.m32; m33 = source.m33;
        }
       
        public void postMultiply(Matrix3 v)
        {
                multiply(this, this, v);
        }
       
        public void preMultiply(Matrix3 v)
        {
                multiply(this, v, this);
        }
       
        static public void multiply(Matrix3 result, Matrix3 a, Matrix3 b)
        {
        float result11 = a.m11 * b.m11 + a.m21 * b.m12 + a.m31 * b.m13;
        float result21 = a.m11 * b.m21 + a.m21 * b.m22 + a.m31 * b.m23;
        float result31 = a.m11 * b.m31 + a.m21 * b.m32 + a.m31 * b.m33;
        float result12 = a.m12 * b.m11 + a.m22 * b.m12 + a.m32 * b.m13;
        float result22 = a.m12 * b.m21 + a.m22 * b.m22 + a.m32 * b.m23;
        float result32 = a.m12 * b.m31 + a.m22 * b.m32 + a.m32 * b.m33;
        float result13 = a.m13 * b.m11 + a.m23 * b.m12 + a.m33 * b.m13;
        float result23 = a.m13 * b.m21 + a.m23 * b.m22 + a.m33 * b.m23;
        float result33 = a.m13 * b.m31 + a.m23 * b.m32 + a.m33 * b.m33;
        result.m11 = result11;
        result.m21 = result21;
        result.m31 = result31;
        result.m12 = result12;
        result.m22 = result22;
        result.m32 = result32;
        result.m13 = result13;
        result.m23 = result23;
        result.m33 = result33;
        }
       
        static public Matrix3 multiply(Matrix3 a, Matrix3 b)
        {
                Matrix3 result = new Matrix3();
                multiply(result, a, b);
                return result;
        }
       
        static public Matrix3 createIdentity()
        {
                return createScale(1.0f, 1.0f, 1.0f);
        }
       
        static public Matrix3 createScale(float sx, float sy, float sz)
        {
                Matrix3 result = new Matrix3();
               
                result.m11 = sx;
                result.m22 = sy;
                result.m33 = sz;
               
                return result;         
        }
       
        static public Matrix3 createScale(Vector3 scale)
        {
                return createScale(scale.x, scale.y, scale.z);
        }
       
        static public Matrix3 createScale(float s)
        {
                return createScale(s, s, s);
        }
       
        static public Matrix3 createRotationX(float degrees)
        {
        float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

        Matrix3 matrix = createIdentity();
        matrix.m22 = cosvalue;
        matrix.m32 = -sinvalue;
        matrix.m23 = sinvalue;
        matrix.m33 = cosvalue;
        return matrix;
        }
       
        static public Matrix3 createRotationY(float degrees)
        {
        float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

        Matrix3 matrix = createIdentity();
        matrix.m11 = cosvalue;
        matrix.m31 = sinvalue;
        matrix.m13 = -sinvalue;
        matrix.m33 = cosvalue;
        return matrix;
        }
       
        static public Matrix3 createRotationZ(float degrees)
        {
        float degreesrad = MathUtil.degToRad(degrees);
        float sinvalue = (float)Math.sin(degreesrad);
        float cosvalue = (float)Math.cos(degreesrad);

        Matrix3 matrix = createIdentity();
        matrix.m11 = cosvalue;
        matrix.m21 = -sinvalue;
        matrix.m12 = sinvalue;
        matrix.m22 = cosvalue;
        return matrix;
        }
       
        static public Matrix3 createRotation(Vector3 axis, float degrees)
        {
        float radangle = MathUtil.degToRad(degrees);
        float radcos = (float)Math.cos(radangle);
        float radsin = (float)Math.sin(radangle);

        Matrix3 matrix = new Matrix3();
        matrix.m11 = radcos + axis.x * axis.x * (1 - radcos);
        matrix.m21 = axis.z * radsin + axis.y * axis.x * (1 - radcos);
        matrix.m31 = -axis.y * radsin + axis.z * axis.x * (1 - radcos);
        matrix.m12 = -axis.z * radsin + axis.x * axis.y * (1 - radcos);
        matrix.m22 = radcos + axis.y * axis.y * (1 - radcos);
        matrix.m32 = axis.x * radsin + axis.z * axis.y * (1 - radcos);
        matrix.m13 = axis.y * radsin + axis.x * axis.z * (1 - radcos);
        matrix.m23 = -axis.x * radsin + axis.y * axis.z * (1 - radcos);
        matrix.m33 = radcos + axis.z * axis.z * (1 - radcos);
        return matrix;
        }
       
        static public Matrix3 createFromVectors(Vector3 forward, Vector3 up, Vector3 right)
        {
        forward.normalize();
        up.normalize();
        right.normalize();
       
        Matrix3 result = createIdentity();
       
        result.m11 = right.x;
        result.m12 = right.y;
        result.m13 = right.z;
        result.m21 = up.x;
        result.m22 = up.y;
        result.m23 = up.z;
        result.m31 = -forward.x;
        result.m32 = -forward.y;
        result.m33 = -forward.z;
       
        return result;
        }
       
        public Vector3 transform(Vector3 vector)
        {
                return new Vector3(
                m11 * vector.x + m21 * vector.y + m31 * vector.z,
                m12 * vector.x + m22 * vector.y + m32 * vector.z,
                m13 * vector.x + m23 * vector.y + m33 * vector.z);
        }
       
        static public void interpolate(Matrix3 result, Matrix3 a, Matrix3 b, float ratio)
        {
        result.m11 = a.m11 + (b.m11 - a.m11) * ratio;
        result.m21 = a.m21 + (b.m21 - a.m21) * ratio;
        result.m31 = a.m31 + (b.m31 - a.m31) * ratio;
        result.m12 = a.m12 + (b.m12 - a.m12) * ratio;
        result.m22 = a.m22 + (b.m22 - a.m22) * ratio;
        result.m32 = a.m32 + (b.m32 - a.m32) * ratio;
        result.m13 = a.m13 + (b.m13 - a.m13) * ratio;
        result.m23 = a.m23 + (b.m23 - a.m23) * ratio;
        result.m33 = a.m33 + (b.m33 - a.m33) * ratio;
        }
       
        static public Matrix3 interpolate(Matrix3 a, Matrix3 b, float ratio)
        {
                Matrix3 result = createIdentity();
                interpolate(result, a, b, ratio);
                return result;
        }
       
        public Vector3 getForwardVector()
        {
                Vector3 forward = new Vector3(-m31, -m32, -m33);
        forward.normalize();
        return forward;
        }
       
        public Vector3 getUpVector()
        {
        Vector3 up = new Vector3(m21, m22, m23);
        up.normalize();
        return up;
        }
       
        public Vector3 getRightVector()
        {
        Vector3 right = new Vector3(m11, m12, m13);
        right.normalize();
        return right;
        }
       
        public float[] toGLMatrix()
        {
                float[] m = new float[16];
               
                m[0] = m11; m[1] = m21; m[2] = m31; m[3] = 0.0f;
                m[4] = m12; m[5] = m22; m[6] = m32; m[7] = 0.0f;
                m[8] = m13; m[9] = m23; m[10] = m33; m[11] = 0.0f;
                m[12] = 0.0f; m[13] = 0.0f; m[14] = 0.0f; m[15] = 1.0f;
               
                return m;
        }      
       
}