Destrovi4 icon

Matrix4f

Destrovi4 | PRO | 02/06/13 10:32:37 AM UTC | 0 ⭐ | 160 👁️ | Never ⏰ | []
Java |

7.18 KB

|

None

|

0 👍

/

0 👎

package destr.math;
 
public class Matrix4f { 
    float[]data;
    public Matrix4f(float[]data) {
        if(data.length > 16) 
            System.err.println(this.getClass().getName()+" length: "+data.length+" > 16");
        this.data = data;
    }
    
    public Matrix4f() {
        // По умолчанию единичная матрица
        data = new float[]{
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1,
        };
    }
    
    public float[] toArray() {
        return data;
    }
    
    public Matrix4f clone() {
        return new Matrix4f(data.clone());
    }
    
    //---
    
    public void multiply(Matrix4f other) {
        multiply(other.toArray());
    }
    
    public void multiply(float[]data2) {
        float a, b, c;
        
        a = data[ 4];
        b = data[ 8];
        c = data[12];
        data[12] = data[0]*data2[12]+ a*data2[13]+ b*data2[14]+ c*data2[15];
        data[ 8] = data[0]*data2[ 8]+ a*data2[ 9]+ b*data2[10]+ c*data2[11];
        data[ 4] = data[0]*data2[ 4]+ a*data2[ 5]+ b*data2[ 6]+ c*data2[ 7];
        data[ 0] = data[0]*data2[ 0]+ a*data2[ 1]+ b*data2[ 2]+ c*data2[ 3];
        
        a = data[ 5];
        b = data[ 9];
        c = data[13];
        data[13] = data[1]*data2[12]+ a*data2[13]+ b*data2[14]+ c*data2[15];
        data[ 9] = data[1]*data2[ 8]+ a*data2[ 9]+ b*data2[10]+ c*data2[11];
        data[ 5] = data[1]*data2[ 4]+ a*data2[ 5]+ b*data2[ 6]+ c*data2[ 7];
        data[ 1] = data[1]*data2[ 0]+ a*data2[ 1]+ b*data2[ 2]+ c*data2[ 3];
        
        a = data[ 6];
        b = data[10];
        c = data[14];
        data[14] = data[2]*data2[12]+ a*data2[13]+ b*data2[14]+ c*data2[15];
        data[10] = data[2]*data2[ 8]+ a*data2[ 9]+ b*data2[10]+ c*data2[11];
        data[ 6] = data[2]*data2[ 4]+ a*data2[ 5]+ b*data2[ 6]+ c*data2[ 7];
        data[ 2] = data[2]*data2[ 0]+ a*data2[ 1]+ b*data2[ 2]+ c*data2[ 3];
        
        a = data[ 7];
        b = data[11];
        c = data[15];
        data[15] = data[3]*data2[12]+ a*data2[13]+ b*data2[14]+ c*data2[15];
        data[11] = data[3]*data2[ 8]+ a*data2[ 9]+ b*data2[10]+ c*data2[11];
        data[ 7] = data[3]*data2[ 4]+ a*data2[ 5]+ b*data2[ 6]+ c*data2[ 7];
        data[ 3] = data[3]*data2[ 0]+ a*data2[ 1]+ b*data2[ 2]+ c*data2[ 3];
    }
    
    public void moveForward(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] += data[ 2] * mDelta;
        data[13] += data[ 6] * mDelta;
        data[14] += data[10] * mDelta;
    }
    public void moveBack(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] -= data[ 2] * mDelta;
        data[13] -= data[ 6] * mDelta;
        data[14] -= data[10] * mDelta;
    }
    
    public void moveUp(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] += data[ 1] * mDelta;
        data[13] += data[ 5] * mDelta;
        data[14] += data[ 9] * mDelta;
    }
    public void moveDown(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] -= data[ 1] * mDelta;
        data[13] -= data[ 5] * mDelta;
        data[14] -= data[ 9] * mDelta;
    }
    
    public void moveLeft(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] += data[ 0] * mDelta;
        data[13] += data[ 4] * mDelta;
        data[14] += data[ 8] * mDelta;
    }
    public void moveRight(float delta){
        float mDelta = delta / (float)Math.sqrt(data[2]*data[2] + data[6]*data[6] + data[10]*data[10]);
        data[12] -= data[ 0] * mDelta;
        data[13] -= data[ 4] * mDelta;
        data[14] -= data[ 8] * mDelta;
    }
    
    public void translite(float[] vector){
        this.multiply(new float[]{
            1,          0,          0,          0,
            0,          1,          0,          0,
            0,          0,          1,          0,
            vector[0],  vector[1],  vector[2],  1,
        });
        
    }
    
    public String toString(){
        return super.toString()+'\n'+
        data[ 0] + ", " + data[ 1] + ", " + data[ 2] + ", " + data[ 3] + ",\n" + 
        data[ 4] + ", " + data[ 5] + ", " + data[ 6] + ", " + data[ 7] + ",\n" +
        data[ 8] + ", " + data[ 9] + ", " + data[10] + ", " + data[11] + ",\n" +
        data[12] + ", " + data[13] + ", " + data[14] + ", " + data[15] + ",\n" ;
    }
    
    
    public static Matrix4f makeFrustum(
        float l,// left
        float r,// right
        float b,// button
        float t,// top
        float n,// near
        float f // far
    ) {
        
        float   t1 = 2.0f * n,
                t2 = r - l,
                t3 = t - b,
                t4 = f - n;
        
        return new Matrix4f(new float[]{
            t1/t2,      0,          0,          0,
            0,          t1/t3,      0,          0,
            (r+l)/t2,   (t+b)/t3,   (-f-n)/t4,  -1,
            0,          0,          -t1*f/t4,   0,
        });
    }
    
    public static float[] lookAt(float[] position, float[] center3D, float[] upVector3D){
        /*
        float[] back = Vector3f.normalize(Vector3f.subtract(center3D, position));
        float[] left = Vector3f.normalize(Vector3f.normal(back, upVector3D));
        float[] up = Vector3f.normal(left, back);
        
        return multiply(new float[]{
            left[0],    up[0],  -back[0],   0,
            left[1],    up[1],  -back[1],   0,
            left[2],    up[2],  -back[2],   0,
            0,          0,      0,          1,
        }, new float[]{
            1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            -position[0],-position[1],-position[2],1,
        });*/
        
        //http://gamedev.chat.ru/articles/a0029.html
        float[] fwd = Vector3f.normalize(Vector3f.subtract( position, center3D));
        float[] left = Vector3f.normalize(Vector3f.normal( upVector3D, fwd));
        float[] up = Vector3f.normal(fwd, left);
        return new float[]{
            left[0],    up[0],  fwd[0], 0,
            left[1],    up[1],  fwd[1], 0,
            left[2],    up[2],  fwd[2], 0,
            -Vector3f.dot(position, left),
            -Vector3f.dot(position, up),
            -Vector3f.dot(position, fwd),1,
        };
    }
    
    public static Matrix4f makeByCols(float[]a, float[]b, float[]c){
        return new Matrix4f(new float[]{
            a[0],   b[0],   c[0],   0,
            a[1],   b[1],   c[1],   0,
            a[2],   b[2],   c[2],   0,
            0,  0,  0,  1,
        });
    }
    
    public static Matrix4f multiply(Matrix4f matrix1, Matrix4f matrix2){
        return new Matrix4f(multiply(matrix1.toArray(), matrix2.toArray()));
    }
    
    public static float[] multiply(float[]data1, float[]data2){
        return new float []{
            data1[0]*data2[ 0]+data1[4]*data2[ 1]+data1[ 8]*data2[ 2]+data1[12]*data2[ 3],
            data1[1]*data2[ 0]+data1[5]*data2[ 1]+data1[ 9]*data2[ 2]+data1[13]*data2[ 3],
            data1[2]*data2[ 0]+data1[6]*data2[ 1]+data1[10]*data2[ 2]+data1[14]*data2[ 3],
            data1[3]*data2[ 0]+data1[7]*data2[ 1]+data1[11]*data2[ 2]+data1[15]*data2[ 3],
            data1[0]*data2[ 4]+data1[4]*data2[ 5]+data1[ 8]*data2[ 6]+data1[12]*data2[ 7],
            data1[1]*data2[ 4]+data1[5]*data2[ 5]+data1[ 9]*data2[ 6]+data1[13]*data2[ 7],                  
            data1[2]*data2[ 4]+data1[6]*data2[ 5]+data1[10]*data2[ 6]+data1[14]*data2[ 7],                  
            data1[3]*data2[ 4]+data1[7]*data2[ 5]+data1[11]*data2[ 6]+data1[15]*data2[ 7],
            data1[0]*data2[ 8]+data1[4]*data2[ 9]+data1[ 8]*data2[10]+data1[12]*data2[11],                  
            data1[1]*data2[ 8]+data1[5]*data2[ 9]+data1[ 9]*data2[10]+data1[13]*data2[11],
            data1[2]*data2[ 8]+data1[6]*data2[ 9]+data1[10]*data2[10]+data1[14]*data2[11],                  
            data1[3]*data2[ 8]+data1[7]*data2[ 9]+data1[11]*data2[10]+data1[15]*data2[11],
            data1[0]*data2[12]+data1[4]*data2[13]+data1[ 8]*data2[14]+data1[12]*data2[15],
            data1[1]*data2[12]+data1[5]*data2[13]+data1[ 9]*data2[14]+data1[13]*data2[15],
            data1[2]*data2[12]+data1[6]*data2[13]+data1[10]*data2[14]+data1[14]*data2[15],
            data1[3]*data2[12]+data1[7]*data2[13]+data1[11]*data2[14]+data1[15]*data2[15],
        };
    }
}

Comments