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
;
}
}