/**
* Copyright 2008 - 2015 The Loon Game Engine Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.5
*/
package loon.geom;
import java.io.Serializable;
import java.nio.FloatBuffer;
import loon.LSystem;
import loon.Support;
import loon.utils.MathUtils;
import loon.utils.NumberUtils;
public class Matrix4 implements Serializable, XY {
/**
*
*/
private static final long serialVersionUID = 4331834668907675786L;
public final static Matrix4 TMP() {
return new Matrix4();
}
public final static Matrix4 ZERO() {
return new Matrix4();
}
public static final int M00 = 0;
public static final int M01 = 4;
public static final int M02 = 8;
public static final int M03 = 12;
public static final int M10 = 1;
public static final int M11 = 5;
public static final int M12 = 9;
public static final int M13 = 13;
public static final int M20 = 2;
public static final int M21 = 6;
public static final int M22 = 10;
public static final int M23 = 14;
public static final int M30 = 3;
public static final int M31 = 7;
public static final int M32 = 11;
public static final int M33 = 15;
public static final float tmp[] = new float[16];
public final float val[] = new float[16];
private Support support;
private void init() {
if (LSystem.base() != null && support == null) {
support = LSystem.base().support();
}
}
public Matrix4() {
val[M00] = 1f;
val[M11] = 1f;
val[M22] = 1f;
val[M33] = 1f;
init();
}
public Matrix4(Matrix4 matrix) {
init();
this.set(matrix);
}
public Matrix4(float[] values) {
init();
this.set(values);
}
public Matrix4(Quaternion quaternion) {
init();
this.set(quaternion);
}
public Matrix4(Vector3f position, Quaternion rotation, Vector3f scale) {
init();
set(position, rotation, scale);
}
public Matrix4 set(Matrix4 matrix) {
return this.set(matrix.val);
}
public Matrix4 set(float[] values) {
System.arraycopy(values, 0, val, 0, val.length);
return this;
}
public Matrix4 set(Quaternion quaternion) {
return set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
}
public Matrix4 set(float quaternionX, float quaternionY, float quaternionZ,
float quaternionW) {
return set(0f, 0f, 0f, quaternionX, quaternionY, quaternionZ,
quaternionW);
}
public Matrix4 set(Vector3f position, Quaternion orientation) {
return set(position.x, position.y, position.z, orientation.x,
orientation.y, orientation.z, orientation.w);
}
public Matrix4 set(float translationX, float translationY,
float translationZ, float quaternionX, float quaternionY,
float quaternionZ, float quaternionW) {
final float xs = quaternionX * 2f, ys = quaternionY * 2f, zs = quaternionZ * 2f;
final float wx = quaternionW * xs, wy = quaternionW * ys, wz = quaternionW
* zs;
final float xx = quaternionX * xs, xy = quaternionX * ys, xz = quaternionX
* zs;
final float yy = quaternionY * ys, yz = quaternionY * zs, zz = quaternionZ
* zs;
val[M00] = (1.0f - (yy + zz));
val[M01] = (xy - wz);
val[M02] = (xz + wy);
val[M03] = translationX;
val[M10] = (xy + wz);
val[M11] = (1.0f - (xx + zz));
val[M12] = (yz - wx);
val[M13] = translationY;
val[M20] = (xz - wy);
val[M21] = (yz + wx);
val[M22] = (1.0f - (xx + yy));
val[M23] = translationZ;
val[M30] = 0.f;
val[M31] = 0.f;
val[M32] = 0.f;
val[M33] = 1.0f;
return this;
}
public Matrix4 set(Vector3f position, Quaternion orientation, Vector3f scale) {
return set(position.x, position.y, position.z, orientation.x,
orientation.y, orientation.z, orientation.w, scale.x, scale.y,
scale.z);
}
public Matrix4 set(float translationX, float translationY,
float translationZ, float quaternionX, float quaternionY,
float quaternionZ, float quaternionW, float scaleX, float scaleY,
float scaleZ) {
final float xs = quaternionX * 2f, ys = quaternionY * 2f, zs = quaternionZ * 2f;
final float wx = quaternionW * xs, wy = quaternionW * ys, wz = quaternionW
* zs;
final float xx = quaternionX * xs, xy = quaternionX * ys, xz = quaternionX
* zs;
final float yy = quaternionY * ys, yz = quaternionY * zs, zz = quaternionZ
* zs;
val[M00] = scaleX * (1.0f - (yy + zz));
val[M01] = scaleY * (xy - wz);
val[M02] = scaleZ * (xz + wy);
val[M03] = translationX;
val[M10] = scaleX * (xy + wz);
val[M11] = scaleY * (1.0f - (xx + zz));
val[M12] = scaleZ * (yz - wx);
val[M13] = translationY;
val[M20] = scaleX * (xz - wy);
val[M21] = scaleY * (yz + wx);
val[M22] = scaleZ * (1.0f - (xx + yy));
val[M23] = translationZ;
val[M30] = 0.f;
val[M31] = 0.f;
val[M32] = 0.f;
val[M33] = 1.0f;
return this;
}
public Matrix4 set(Vector3f xAxis, Vector3f yAxis, Vector3f zAxis,
Vector3f pos) {
val[M00] = xAxis.x;
val[M01] = xAxis.y;
val[M02] = xAxis.z;
val[M10] = yAxis.x;
val[M11] = yAxis.y;
val[M12] = yAxis.z;
val[M20] = zAxis.x;
val[M21] = zAxis.y;
val[M22] = zAxis.z;
val[M03] = pos.x;
val[M13] = pos.y;
val[M23] = pos.z;
val[M30] = 0;
val[M31] = 0;
val[M32] = 0;
val[M33] = 1;
return this;
}
public Matrix4 set(int x, int y, float v) {
val[y + x * 4] = v;
return this;
}
public float get(int x, int y) {
return val[y + x * 4];
}
public Matrix4 cpy() {
return new Matrix4(this);
}
public Matrix4 trn(Vector3f vector) {
val[M03] += vector.x;
val[M13] += vector.y;
val[M23] += vector.z;
return this;
}
public Matrix4 trn(float x, float y, float z) {
val[M03] += x;
val[M13] += y;
val[M23] += z;
return this;
}
public float[] getValues() {
return val;
}
public Matrix4 mul(Matrix4 matrix) {
support.mul(val, matrix.val);
return this;
}
public Matrix4 mul(Affine2f aff) {
Matrix4 m = new Matrix4();
m.set(aff);
support.mul(val, m.val);
return this;
}
public Matrix4 mulLeft(Matrix4 matrix) {
tmpMat.set(matrix);
support.mul(tmpMat.val, this.val);
return set(tmpMat);
}
public Matrix4 tra() {
tmp[M00] = val[M00];
tmp[M01] = val[M10];
tmp[M02] = val[M20];
tmp[M03] = val[M30];
tmp[M10] = val[M01];
tmp[M11] = val[M11];
tmp[M12] = val[M21];
tmp[M13] = val[M31];
tmp[M20] = val[M02];
tmp[M21] = val[M12];
tmp[M22] = val[M22];
tmp[M23] = val[M32];
tmp[M30] = val[M03];
tmp[M31] = val[M13];
tmp[M32] = val[M23];
tmp[M33] = val[M33];
return set(tmp);
}
public Matrix4 idt() {
val[M00] = 1;
val[M01] = 0;
val[M02] = 0;
val[M03] = 0;
val[M10] = 0;
val[M11] = 1;
val[M12] = 0;
val[M13] = 0;
val[M20] = 0;
val[M21] = 0;
val[M22] = 1;
val[M23] = 0;
val[M30] = 0;
val[M31] = 0;
val[M32] = 0;
val[M33] = 1;
return this;
}
public Matrix4 izero() {
val[M00] = 0;
val[M01] = 0;
val[M02] = 0;
val[M03] = 0;
val[M10] = 0;
val[M11] = 0;
val[M12] = 0;
val[M13] = 0;
val[M20] = 0;
val[M21] = 0;
val[M22] = 0;
val[M23] = 0;
val[M30] = 0;
val[M31] = 0;
val[M32] = 0;
val[M33] = 0;
return this;
}
public Matrix4 inv() {
float l_det = val[M30] * val[M21] * val[M12] * val[M03] - val[M20]
* val[M31] * val[M12] * val[M03] - val[M30] * val[M11]
* val[M22] * val[M03] + val[M10] * val[M31] * val[M22]
* val[M03] + val[M20] * val[M11] * val[M32] * val[M03]
- val[M10] * val[M21] * val[M32] * val[M03] - val[M30]
* val[M21] * val[M02] * val[M13] + val[M20] * val[M31]
* val[M02] * val[M13] + val[M30] * val[M01] * val[M22]
* val[M13] - val[M00] * val[M31] * val[M22] * val[M13]
- val[M20] * val[M01] * val[M32] * val[M13] + val[M00]
* val[M21] * val[M32] * val[M13] + val[M30] * val[M11]
* val[M02] * val[M23] - val[M10] * val[M31] * val[M02]
* val[M23] - val[M30] * val[M01] * val[M12] * val[M23]
+ val[M00] * val[M31] * val[M12] * val[M23] + val[M10]
* val[M01] * val[M32] * val[M23] - val[M00] * val[M11]
* val[M32] * val[M23] - val[M20] * val[M11] * val[M02]
* val[M33] + val[M10] * val[M21] * val[M02] * val[M33]
+ val[M20] * val[M01] * val[M12] * val[M33] - val[M00]
* val[M21] * val[M12] * val[M33] - val[M10] * val[M01]
* val[M22] * val[M33] + val[M00] * val[M11] * val[M22]
* val[M33];
if (l_det == 0f) {
throw LSystem.runThrow("non-invertible matrix");
}
float inv_det = 1.0f / l_det;
tmp[M00] = val[M12] * val[M23] * val[M31] - val[M13] * val[M22]
* val[M31] + val[M13] * val[M21] * val[M32] - val[M11]
* val[M23] * val[M32] - val[M12] * val[M21] * val[M33]
+ val[M11] * val[M22] * val[M33];
tmp[M01] = val[M03] * val[M22] * val[M31] - val[M02] * val[M23]
* val[M31] - val[M03] * val[M21] * val[M32] + val[M01]
* val[M23] * val[M32] + val[M02] * val[M21] * val[M33]
- val[M01] * val[M22] * val[M33];
tmp[M02] = val[M02] * val[M13] * val[M31] - val[M03] * val[M12]
* val[M31] + val[M03] * val[M11] * val[M32] - val[M01]
* val[M13] * val[M32] - val[M02] * val[M11] * val[M33]
+ val[M01] * val[M12] * val[M33];
tmp[M03] = val[M03] * val[M12] * val[M21] - val[M02] * val[M13]
* val[M21] - val[M03] * val[M11] * val[M22] + val[M01]
* val[M13] * val[M22] + val[M02] * val[M11] * val[M23]
- val[M01] * val[M12] * val[M23];
tmp[M10] = val[M13] * val[M22] * val[M30] - val[M12] * val[M23]
* val[M30] - val[M13] * val[M20] * val[M32] + val[M10]
* val[M23] * val[M32] + val[M12] * val[M20] * val[M33]
- val[M10] * val[M22] * val[M33];
tmp[M11] = val[M02] * val[M23] * val[M30] - val[M03] * val[M22]
* val[M30] + val[M03] * val[M20] * val[M32] - val[M00]
* val[M23] * val[M32] - val[M02] * val[M20] * val[M33]
+ val[M00] * val[M22] * val[M33];
tmp[M12] = val[M03] * val[M12] * val[M30] - val[M02] * val[M13]
* val[M30] - val[M03] * val[M10] * val[M32] + val[M00]
* val[M13] * val[M32] + val[M02] * val[M10] * val[M33]
- val[M00] * val[M12] * val[M33];
tmp[M13] = val[M02] * val[M13] * val[M20] - val[M03] * val[M12]
* val[M20] + val[M03] * val[M10] * val[M22] - val[M00]
* val[M13] * val[M22] - val[M02] * val[M10] * val[M23]
+ val[M00] * val[M12] * val[M23];
tmp[M20] = val[M11] * val[M23] * val[M30] - val[M13] * val[M21]
* val[M30] + val[M13] * val[M20] * val[M31] - val[M10]
* val[M23] * val[M31] - val[M11] * val[M20] * val[M33]
+ val[M10] * val[M21] * val[M33];
tmp[M21] = val[M03] * val[M21] * val[M30] - val[M01] * val[M23]
* val[M30] - val[M03] * val[M20] * val[M31] + val[M00]
* val[M23] * val[M31] + val[M01] * val[M20] * val[M33]
- val[M00] * val[M21] * val[M33];
tmp[M22] = val[M01] * val[M13] * val[M30] - val[M03] * val[M11]
* val[M30] + val[M03] * val[M10] * val[M31] - val[M00]
* val[M13] * val[M31] - val[M01] * val[M10] * val[M33]
+ val[M00] * val[M11] * val[M33];
tmp[M23] = val[M03] * val[M11] * val[M20] - val[M01] * val[M13]
* val[M20] - val[M03] * val[M10] * val[M21] + val[M00]
* val[M13] * val[M21] + val[M01] * val[M10] * val[M23]
- val[M00] * val[M11] * val[M23];
tmp[M30] = val[M12] * val[M21] * val[M30] - val[M11] * val[M22]
* val[M30] - val[M12] * val[M20] * val[M31] + val[M10]
* val[M22] * val[M31] + val[M11] * val[M20] * val[M32]
- val[M10] * val[M21] * val[M32];
tmp[M31] = val[M01] * val[M22] * val[M30] - val[M02] * val[M21]
* val[M30] + val[M02] * val[M20] * val[M31] - val[M00]
* val[M22] * val[M31] - val[M01] * val[M20] * val[M32]
+ val[M00] * val[M21] * val[M32];
tmp[M32] = val[M02] * val[M11] * val[M30] - val[M01] * val[M12]
* val[M30] - val[M02] * val[M10] * val[M31] + val[M00]
* val[M12] * val[M31] + val[M01] * val[M10] * val[M32]
- val[M00] * val[M11] * val[M32];
tmp[M33] = val[M01] * val[M12] * val[M20] - val[M02] * val[M11]
* val[M20] + val[M02] * val[M10] * val[M21] - val[M00]
* val[M12] * val[M21] - val[M01] * val[M10] * val[M22]
+ val[M00] * val[M11] * val[M22];
val[M00] = tmp[M00] * inv_det;
val[M01] = tmp[M01] * inv_det;
val[M02] = tmp[M02] * inv_det;
val[M03] = tmp[M03] * inv_det;
val[M10] = tmp[M10] * inv_det;
val[M11] = tmp[M11] * inv_det;
val[M12] = tmp[M12] * inv_det;
val[M13] = tmp[M13] * inv_det;
val[M20] = tmp[M20] * inv_det;
val[M21] = tmp[M21] * inv_det;
val[M22] = tmp[M22] * inv_det;
val[M23] = tmp[M23] * inv_det;
val[M30] = tmp[M30] * inv_det;
val[M31] = tmp[M31] * inv_det;
val[M32] = tmp[M32] * inv_det;
val[M33] = tmp[M33] * inv_det;
return this;
}
public float det() {
return val[M30] * val[M21] * val[M12] * val[M03] - val[M20] * val[M31]
* val[M12] * val[M03] - val[M30] * val[M11] * val[M22]
* val[M03] + val[M10] * val[M31] * val[M22] * val[M03]
+ val[M20] * val[M11] * val[M32] * val[M03] - val[M10]
* val[M21] * val[M32] * val[M03] - val[M30] * val[M21]
* val[M02] * val[M13] + val[M20] * val[M31] * val[M02]
* val[M13] + val[M30] * val[M01] * val[M22] * val[M13]
- val[M00] * val[M31] * val[M22] * val[M13] - val[M20]
* val[M01] * val[M32] * val[M13] + val[M00] * val[M21]
* val[M32] * val[M13] + val[M30] * val[M11] * val[M02]
* val[M23] - val[M10] * val[M31] * val[M02] * val[M23]
- val[M30] * val[M01] * val[M12] * val[M23] + val[M00]
* val[M31] * val[M12] * val[M23] + val[M10] * val[M01]
* val[M32] * val[M23] - val[M00] * val[M11] * val[M32]
* val[M23] - val[M20] * val[M11] * val[M02] * val[M33]
+ val[M10] * val[M21] * val[M02] * val[M33] + val[M20]
* val[M01] * val[M12] * val[M33] - val[M00] * val[M21]
* val[M12] * val[M33] - val[M10] * val[M01] * val[M22]
* val[M33] + val[M00] * val[M11] * val[M22] * val[M33];
}
public float det3x3() {
return val[M00] * val[M11] * val[M22] + val[M01] * val[M12] * val[M20]
+ val[M02] * val[M10] * val[M21] - val[M00] * val[M12]
* val[M21] - val[M01] * val[M10] * val[M22] - val[M02]
* val[M11] * val[M20];
}
public Matrix4 setToProjection(float near, float far, float fovy,
float aspectRatio) {
float l_fd = (1f / MathUtils.tan(fovy * MathUtils.DEG_TO_RAD) / 2f);
float l_a1 = (far + near) / (near - far);
float l_a2 = (2 * far * near) / (near - far);
val[M00] = l_fd / aspectRatio;
val[M10] = 0;
val[M20] = 0;
val[M30] = 0;
val[M01] = 0;
val[M11] = l_fd;
val[M21] = 0;
val[M31] = 0;
val[M02] = 0;
val[M12] = 0;
val[M22] = l_a1;
val[M32] = -1;
val[M03] = 0;
val[M13] = 0;
val[M23] = l_a2;
val[M33] = 0;
return this;
}
public Matrix4 setToOrtho2D(float x, float y, float width, float height) {
setToOrtho(x, x + width, y + height, y, 1f, -1f);
return this;
}
public Matrix4 setToOrtho2D(float x, float y, float width, float height,
float near, float far) {
setToOrtho(x, x + width, y + height, y, near, far);
return this;
}
public Matrix4 setToOrtho(float left, float right, float bottom, float top,
float near, float far) {
float x_orth = 2 / (right - left);
float y_orth = 2 / (top - bottom);
float z_orth = -2 / (far - near);
float tx = -(right + left) / (right - left);
float ty = -(top + bottom) / (top - bottom);
float tz = -(far + near) / (far - near);
val[M00] = x_orth;
val[M10] = 0;
val[M20] = 0;
val[M30] = 0;
val[M01] = 0;
val[M11] = y_orth;
val[M21] = 0;
val[M31] = 0;
val[M02] = 0;
val[M12] = 0;
val[M22] = z_orth;
val[M32] = 0;
val[M03] = tx;
val[M13] = ty;
val[M23] = tz;
val[M33] = 1;
return this;
}
public Matrix4 setTranslation(Vector3f vector) {
val[M03] = vector.x;
val[M13] = vector.y;
val[M23] = vector.z;
return this;
}
public Matrix4 setTranslation(float x, float y, float z) {
val[M03] = x;
val[M13] = y;
val[M23] = z;
return this;
}
public Matrix4 setToTranslation(Vector3f vector) {
idt();
val[M03] = vector.x;
val[M13] = vector.y;
val[M23] = vector.z;
return this;
}
public Matrix4 setToTranslation(float x, float y, float z) {
idt();
val[M03] = x;
val[M13] = y;
val[M23] = z;
return this;
}
public Matrix4 setToTranslationAndScaling(Vector3f translation,
Vector3f scaling) {
idt();
val[M03] = translation.x;
val[M13] = translation.y;
val[M23] = translation.z;
val[M00] = scaling.x;
val[M11] = scaling.y;
val[M22] = scaling.z;
return this;
}
public Matrix4 setToTranslationAndScaling(float translationX,
float translationY, float translationZ, float scalingX,
float scalingY, float scalingZ) {
idt();
val[M03] = translationX;
val[M13] = translationY;
val[M23] = translationZ;
val[M00] = scalingX;
val[M11] = scalingY;
val[M22] = scalingZ;
return this;
}
static Quaternion quat = new Quaternion();
static Quaternion quat2 = new Quaternion();
public Matrix4 setToRotation(Vector3f axis, float degrees) {
if (degrees == 0) {
idt();
return this;
}
return set(quat.set(axis, degrees));
}
public Matrix4 setToRotationRad(Vector3f axis, float radians) {
if (radians == 0) {
idt();
return this;
}
return set(quat.setFromAxisRad(axis, radians));
}
public Matrix4 setToRotation(float axisX, float axisY, float axisZ,
float degrees) {
if (degrees == 0) {
idt();
return this;
}
return set(quat.setFromAxis(axisX, axisY, axisZ, degrees));
}
public Matrix4 setToRotationRad(float axisX, float axisY, float axisZ,
float radians) {
if (radians == 0) {
idt();
return this;
}
return set(quat.setFromAxisRad(axisX, axisY, axisZ, radians));
}
public Matrix4 setToRotation(final Vector3f v1, final Vector3f v2) {
return set(quat.setFromCross(v1, v2));
}
public Matrix4 setToRotation(final float x1, final float y1,
final float z1, final float x2, final float y2, final float z2) {
return set(quat.setFromCross(x1, y1, z1, x2, y2, z2));
}
public Matrix4 setFromEulerAngles(float yaw, float pitch, float roll) {
quat.setEulerAnglesSelf(yaw, pitch, roll);
return set(quat);
}
public Matrix4 setToScaling(Vector3f vector) {
idt();
val[M00] = vector.x;
val[M11] = vector.y;
val[M22] = vector.z;
return this;
}
public Matrix4 setToScaling(float x, float y, float z) {
idt();
val[M00] = x;
val[M11] = y;
val[M22] = z;
return this;
}
static final Vector3f l_vez = new Vector3f();
static final Vector3f l_vex = new Vector3f();
static final Vector3f l_vey = new Vector3f();
public Matrix4 setToLookAt(Vector3f direction, Vector3f up) {
l_vez.set(direction).norSelf();
l_vex.set(direction).norSelf();
l_vex.crsSelf(up).norSelf();
l_vey.set(l_vex).crsSelf(l_vez).norSelf();
idt();
val[M00] = l_vex.x;
val[M01] = l_vex.y;
val[M02] = l_vex.z;
val[M10] = l_vey.x;
val[M11] = l_vey.y;
val[M12] = l_vey.z;
val[M20] = -l_vez.x;
val[M21] = -l_vez.y;
val[M22] = -l_vez.z;
return this;
}
static final Vector3f tmpVec = new Vector3f();
static final Matrix4 tmpMat = new Matrix4();
public Matrix4 setToLookAt(Vector3f position, Vector3f target, Vector3f up) {
tmpVec.set(target).subtractSelf(position);
setToLookAt(tmpVec, up);
this.mul(tmpMat.setToTranslation(-position.x, -position.y, -position.z));
return this;
}
static final Vector3f right = new Vector3f();
static final Vector3f tmpForward = new Vector3f();
static final Vector3f tmpUp = new Vector3f();
public Matrix4 setToWorld(Vector3f position, Vector3f forward, Vector3f up) {
tmpForward.set(forward).norSelf();
right.set(tmpForward).crsSelf(up).norSelf();
tmpUp.set(right).crsSelf(tmpForward).norSelf();
this.set(right, tmpUp, tmpForward.scaleSelf(-1), position);
return this;
}
public String toString() {
return "[" + val[M00] + "|" + val[M01] + "|" + val[M02] + "|"
+ val[M03] + "]\n" + "[" + val[M10] + "|" + val[M11] + "|"
+ val[M12] + "|" + val[M13] + "]\n" + "[" + val[M20] + "|"
+ val[M21] + "|" + val[M22] + "|" + val[M23] + "]\n" + "["
+ val[M30] + "|" + val[M31] + "|" + val[M32] + "|" + val[M33]
+ "]\n";
}
public Matrix4 lerp(Matrix4 matrix, float alpha) {
for (int i = 0; i < 16; i++)
this.val[i] = this.val[i] * (1 - alpha) + matrix.val[i] * alpha;
return this;
}
public Matrix4 avg(Matrix4 other, float w) {
getScale(tmpVec);
other.getScale(tmpForward);
getRotation(quat);
other.getRotation(quat2);
getTranslation(tmpUp);
other.getTranslation(right);
setToScaling(tmpVec.scaleSelf(w).addSelf(tmpForward.scaleSelf(1 - w)));
rotate(quat.slerpSelf(quat2, 1 - w));
setTranslation(tmpUp.scaleSelf(w).addSelf(right.scaleSelf(1 - w)));
return this;
}
public Matrix4 avg(Matrix4[] t) {
final float w = 1.0f / t.length;
tmpVec.set(t[0].getScale(tmpUp).scaleSelf(w));
quat.set(t[0].getRotation(quat2).expSelf(w));
tmpForward.set(t[0].getTranslation(tmpUp).scaleSelf(w));
for (int i = 1; i < t.length; i++) {
tmpVec.addSelf(t[i].getScale(tmpUp).scaleSelf(w));
quat.mulSelf(t[i].getRotation(quat2).expSelf(w));
tmpForward.addSelf(t[i].getTranslation(tmpUp).scaleSelf(w));
}
quat.norSelf();
setToScaling(tmpVec);
rotate(quat);
setTranslation(tmpForward);
return this;
}
public Matrix4 avg(Matrix4[] t, float[] w) {
tmpVec.set(t[0].getScale(tmpUp).scaleSelf(w[0]));
quat.set(t[0].getRotation(quat2).expSelf(w[0]));
tmpForward.set(t[0].getTranslation(tmpUp).scaleSelf(w[0]));
for (int i = 1; i < t.length; i++) {
tmpVec.addSelf(t[i].getScale(tmpUp).scaleSelf(w[i]));
quat.mulSelf(t[i].getRotation(quat2).expSelf(w[i]));
tmpForward.addSelf(t[i].getTranslation(tmpUp).scaleSelf(w[i]));
}
quat.norSelf();
setToScaling(tmpVec);
rotate(quat);
setTranslation(tmpForward);
return this;
}
public Matrix4 set(Matrix3 mat) {
val[0] = mat.val[0];
val[1] = mat.val[1];
val[2] = mat.val[2];
val[3] = 0;
val[4] = mat.val[3];
val[5] = mat.val[4];
val[6] = mat.val[5];
val[7] = 0;
val[8] = 0;
val[9] = 0;
val[10] = 1;
val[11] = 0;
val[12] = mat.val[6];
val[13] = mat.val[7];
val[14] = 0;
val[15] = mat.val[8];
return this;
}
public Matrix4 setAsAffine(Matrix4 mat) {
val[M00] = mat.val[M00];
val[M10] = mat.val[M10];
val[M01] = mat.val[M01];
val[M11] = mat.val[M11];
val[M03] = mat.val[M03];
val[M13] = mat.val[M13];
return this;
}
public Matrix4 scaleSelf(Vector3f scale) {
val[M00] *= scale.x;
val[M11] *= scale.y;
val[M22] *= scale.z;
return this;
}
public Matrix4 scaleSelf(float x, float y, float z) {
val[M00] *= x;
val[M11] *= y;
val[M22] *= z;
return this;
}
public Matrix4 scaleSelf(float scale) {
val[M00] *= scale;
val[M11] *= scale;
val[M22] *= scale;
return this;
}
public Vector3f getTranslation(Vector3f position) {
position.x = val[M03];
position.y = val[M13];
position.z = val[M23];
return position;
}
public Quaternion getRotation(Quaternion rotation, boolean normalizeAxes) {
return rotation.setFromMatrix(normalizeAxes, this);
}
public Quaternion getRotation(Quaternion rotation) {
return rotation.setFromMatrix(this);
}
public float getScaleXSquared() {
return val[Matrix4.M00] * val[Matrix4.M00] + val[Matrix4.M01]
* val[Matrix4.M01] + val[Matrix4.M02] * val[Matrix4.M02];
}
public float getScaleYSquared() {
return val[Matrix4.M10] * val[Matrix4.M10] + val[Matrix4.M11]
* val[Matrix4.M11] + val[Matrix4.M12] * val[Matrix4.M12];
}
public float getScaleZSquared() {
return val[Matrix4.M20] * val[Matrix4.M20] + val[Matrix4.M21]
* val[Matrix4.M21] + val[Matrix4.M22] * val[Matrix4.M22];
}
public float getScaleX() {
return (MathUtils.isZero(val[Matrix4.M01]) && MathUtils
.isZero(val[Matrix4.M02])) ? MathUtils.abs(val[Matrix4.M00])
: MathUtils.sqrt(getScaleXSquared());
}
public float getScaleY() {
return (MathUtils.isZero(val[Matrix4.M10]) && MathUtils
.isZero(val[Matrix4.M12])) ? MathUtils.abs(val[Matrix4.M11])
: MathUtils.sqrt(getScaleYSquared());
}
public float getScaleZ() {
return (MathUtils.isZero(val[Matrix4.M20]) && MathUtils
.isZero(val[Matrix4.M21])) ? MathUtils.abs(val[Matrix4.M22])
: MathUtils.sqrt(getScaleZSquared());
}
public Vector3f getScale(Vector3f scale) {
return scale.set(getScaleX(), getScaleY(), getScaleZ());
}
public Matrix4 toNormalMatrix() {
val[M03] = 0;
val[M13] = 0;
val[M23] = 0;
return inv().tra();
}
public Matrix4 translate(Vector3f translation) {
return translate(translation.x, translation.y, translation.z);
}
public Matrix4 translate(float x, float y, float z) {
tmp[M00] = 1;
tmp[M01] = 0;
tmp[M02] = 0;
tmp[M03] = x;
tmp[M10] = 0;
tmp[M11] = 1;
tmp[M12] = 0;
tmp[M13] = y;
tmp[M20] = 0;
tmp[M21] = 0;
tmp[M22] = 1;
tmp[M23] = z;
tmp[M30] = 0;
tmp[M31] = 0;
tmp[M32] = 0;
tmp[M33] = 1;
support.mul(val, tmp);
return this;
}
public Matrix4 rotate(Vector3f axis, float degrees) {
if (degrees == 0)
return this;
quat.set(axis, degrees);
return rotate(quat);
}
public Matrix4 rotateRad(Vector3f axis, float radians) {
if (radians == 0)
return this;
quat.setFromAxisRad(axis, radians);
return rotate(quat);
}
public Matrix4 rotate(float axisX, float axisY, float axisZ, float degrees) {
if (degrees == 0)
return this;
quat.setFromAxis(axisX, axisY, axisZ, degrees);
return rotate(quat);
}
public Matrix4 rotateRad(float axisX, float axisY, float axisZ,
float radians) {
if (radians == 0)
return this;
quat.setFromAxisRad(axisX, axisY, axisZ, radians);
return rotate(quat);
}
public Matrix4 rotate(Quaternion rotation) {
rotation.toMatrix(tmp);
support.mul(val, tmp);
return this;
}
public Matrix4 rotate(final Vector3f v1, final Vector3f v2) {
return rotate(quat.setFromCross(v1, v2));
}
public Matrix4 scale(float scaleX, float scaleY, float scaleZ) {
tmp[M00] = scaleX;
tmp[M01] = 0;
tmp[M02] = 0;
tmp[M03] = 0;
tmp[M10] = 0;
tmp[M11] = scaleY;
tmp[M12] = 0;
tmp[M13] = 0;
tmp[M20] = 0;
tmp[M21] = 0;
tmp[M22] = scaleZ;
tmp[M23] = 0;
tmp[M30] = 0;
tmp[M31] = 0;
tmp[M32] = 0;
tmp[M33] = 1;
support.mul(val, tmp);
return this;
}
public void extract4x3Matrix(float[] dst) {
dst[0] = val[M00];
dst[1] = val[M10];
dst[2] = val[M20];
dst[3] = val[M01];
dst[4] = val[M11];
dst[5] = val[M21];
dst[6] = val[M02];
dst[7] = val[M12];
dst[8] = val[M22];
dst[9] = val[M03];
dst[10] = val[M13];
dst[11] = val[M23];
}
public Matrix4 setAsAffine(Affine2f affine) {
val[M00] = affine.m00;
val[M10] = affine.m10;
val[M01] = affine.m01;
val[M11] = affine.m11;
val[M03] = affine.tx;
val[M13] = affine.ty;
return this;
}
public Matrix4 set(Affine2f affine) {
val[M00] = affine.m00;
val[M10] = affine.m10;
val[M20] = 0;
val[M30] = 0;
val[M01] = affine.m01;
val[M11] = affine.m11;
val[M21] = 0;
val[M31] = 0;
val[M02] = 0;
val[M12] = 0;
val[M22] = 1;
val[M32] = 0;
val[M03] = affine.tx;
val[M13] = affine.ty;
val[M23] = 0;
val[M33] = 1;
return this;
}
public Matrix4 newCombine(Affine2f affine) {
float m00 = affine.m00;
float m10 = affine.m10;
float m20 = 0;
float m30 = 0;
float m01 = affine.m01;
float m11 = affine.m11;
float m21 = 0;
float m31 = 0;
float m02 = 0;
float m12 = 0;
float m22 = 1;
float m32 = 0;
float m03 = affine.tx;
float m13 = affine.ty;
float m23 = 0;
float m33 = 1;
float nm00 = val[M00] * m00 + val[M01] * m10 + val[M02] * m20
+ val[M03] * m30;
float nm01 = val[M00] * m01 + val[M01] * m11 + val[M02] * m21
+ val[M03] * m31;
float nm02 = val[M00] * m02 + val[M01] * m12 + val[M02] * m22
+ val[M03] * m32;
float nm03 = val[M00] * m03 + val[M01] * m13 + val[M02] * m23
+ val[M03] * m33;
float nm10 = val[M10] * m00 + val[M11] * m10 + val[M12] * m20
+ val[M13] * m30;
float nm11 = val[M10] * m01 + val[M11] * m11 + val[M12] * m21
+ val[M13] * m31;
float nm12 = val[M10] * m02 + val[M11] * m12 + val[M12] * m22
+ val[M13] * m32;
float nm13 = val[M10] * m03 + val[M11] * m13 + val[M12] * m23
+ val[M13] * m33;
float nm20 = val[M20] * m00 + val[M21] * m10 + val[M22] * m20
+ val[M23] * m30;
float nm21 = val[M20] * m01 + val[M21] * m11 + val[M22] * m21
+ val[M23] * m31;
float nm22 = val[M20] * m02 + val[M21] * m12 + val[M22] * m22
+ val[M23] * m32;
float nm23 = val[M20] * m03 + val[M21] * m13 + val[M22] * m23
+ val[M23] * m33;
float nm30 = val[M30] * m00 + val[M31] * m10 + val[M32] * m20
+ val[M33] * m30;
float nm31 = val[M30] * m01 + val[M31] * m11 + val[M32] * m21
+ val[M33] * m31;
float nm32 = val[M30] * m02 + val[M31] * m12 + val[M32] * m22
+ val[M33] * m32;
float nm33 = val[M30] * m03 + val[M31] * m13 + val[M32] * m23
+ val[M33] * m33;
Matrix4 m = new Matrix4();
m.val[M00] = nm00;
m.val[M10] = nm10;
m.val[M20] = nm20;
m.val[M30] = nm30;
m.val[M01] = nm01;
m.val[M11] = nm11;
m.val[M21] = nm21;
m.val[M31] = nm31;
m.val[M02] = nm02;
m.val[M12] = nm12;
m.val[M22] = nm22;
m.val[M32] = nm32;
m.val[M03] = nm03;
m.val[M13] = nm13;
m.val[M23] = nm23;
m.val[M33] = nm33;
return m;
}
public Matrix4 thisCombine(Affine2f affine) {
final float m00 = affine.m00;
final float m10 = affine.m10;
final float m20 = 0;
final float m30 = 0;
final float m01 = affine.m01;
final float m11 = affine.m11;
final float m21 = 0;
final float m31 = 0;
final float m02 = 0;
final float m12 = 0;
final float m22 = 1;
final float m32 = 0;
final float m03 = affine.tx;
final float m13 = affine.ty;
final float m23 = 0;
final float m33 = 1;
final float nm00 = val[M00] * m00 + val[M01] * m10 + val[M02] * m20
+ val[M03] * m30;
final float nm01 = val[M00] * m01 + val[M01] * m11 + val[M02] * m21
+ val[M03] * m31;
final float nm02 = val[M00] * m02 + val[M01] * m12 + val[M02] * m22
+ val[M03] * m32;
final float nm03 = val[M00] * m03 + val[M01] * m13 + val[M02] * m23
+ val[M03] * m33;
final float nm10 = val[M10] * m00 + val[M11] * m10 + val[M12] * m20
+ val[M13] * m30;
final float nm11 = val[M10] * m01 + val[M11] * m11 + val[M12] * m21
+ val[M13] * m31;
final float nm12 = val[M10] * m02 + val[M11] * m12 + val[M12] * m22
+ val[M13] * m32;
final float nm13 = val[M10] * m03 + val[M11] * m13 + val[M12] * m23
+ val[M13] * m33;
final float nm20 = val[M20] * m00 + val[M21] * m10 + val[M22] * m20
+ val[M23] * m30;
final float nm21 = val[M20] * m01 + val[M21] * m11 + val[M22] * m21
+ val[M23] * m31;
final float nm22 = val[M20] * m02 + val[M21] * m12 + val[M22] * m22
+ val[M23] * m32;
final float nm23 = val[M20] * m03 + val[M21] * m13 + val[M22] * m23
+ val[M23] * m33;
final float nm30 = val[M30] * m00 + val[M31] * m10 + val[M32] * m20
+ val[M33] * m30;
final float nm31 = val[M30] * m01 + val[M31] * m11 + val[M32] * m21
+ val[M33] * m31;
final float nm32 = val[M30] * m02 + val[M31] * m12 + val[M32] * m22
+ val[M33] * m32;
final float nm33 = val[M30] * m03 + val[M31] * m13 + val[M32] * m23
+ val[M33] * m33;
this.val[M00] = nm00;
this.val[M10] = nm10;
this.val[M20] = nm20;
this.val[M30] = nm30;
this.val[M01] = nm01;
this.val[M11] = nm11;
this.val[M21] = nm21;
this.val[M31] = nm31;
this.val[M02] = nm02;
this.val[M12] = nm12;
this.val[M22] = nm22;
this.val[M32] = nm32;
this.val[M03] = nm03;
this.val[M13] = nm13;
this.val[M23] = nm23;
this.val[M33] = nm33;
return this;
}
public static Matrix4 newCombine(Matrix4 m1, Matrix4 m2) {
float m00 = m1.val[M00] * m2.val[M00] + m1.val[M01] * m2.val[M10]
+ m1.val[M02] * m2.val[M20] + m1.val[M03] * m2.val[M30];
float m01 = m1.val[M00] * m2.val[M01] + m1.val[M01] * m2.val[M11]
+ m1.val[M02] * m2.val[M21] + m1.val[M03] * m2.val[M31];
float m02 = m1.val[M00] * m2.val[M02] + m1.val[M01] * m2.val[M12]
+ m1.val[M02] * m2.val[M22] + m1.val[M03] * m2.val[M32];
float m03 = m1.val[M00] * m2.val[M03] + m1.val[M01] * m2.val[M13]
+ m1.val[M02] * m2.val[M23] + m1.val[M03] * m2.val[M33];
float m10 = m1.val[M10] * m2.val[M00] + m1.val[M11] * m2.val[M10]
+ m1.val[M12] * m2.val[M20] + m1.val[M13] * m2.val[M30];
float m11 = m1.val[M10] * m2.val[M01] + m1.val[M11] * m2.val[M11]
+ m1.val[M12] * m2.val[M21] + m1.val[M13] * m2.val[M31];
float m12 = m1.val[M10] * m2.val[M02] + m1.val[M11] * m2.val[M12]
+ m1.val[M12] * m2.val[M22] + m1.val[M13] * m2.val[M32];
float m13 = m1.val[M10] * m2.val[M03] + m1.val[M11] * m2.val[M13]
+ m1.val[M12] * m2.val[M23] + m1.val[M13] * m2.val[M33];
float m20 = m1.val[M20] * m2.val[M00] + m1.val[M21] * m2.val[M10]
+ m1.val[M22] * m2.val[M20] + m1.val[M23] * m2.val[M30];
float m21 = m1.val[M20] * m2.val[M01] + m1.val[M21] * m2.val[M11]
+ m1.val[M22] * m2.val[M21] + m1.val[M23] * m2.val[M31];
float m22 = m1.val[M20] * m2.val[M02] + m1.val[M21] * m2.val[M12]
+ m1.val[M22] * m2.val[M22] + m1.val[M23] * m2.val[M32];
float m23 = m1.val[M20] * m2.val[M03] + m1.val[M21] * m2.val[M13]
+ m1.val[M22] * m2.val[M23] + m1.val[M23] * m2.val[M33];
float m30 = m1.val[M30] * m2.val[M00] + m1.val[M31] * m2.val[M10]
+ m1.val[M32] * m2.val[M20] + m1.val[M33] * m2.val[M30];
float m31 = m1.val[M30] * m2.val[M01] + m1.val[M31] * m2.val[M11]
+ m1.val[M32] * m2.val[M21] + m1.val[M33] * m2.val[M31];
float m32 = m1.val[M30] * m2.val[M02] + m1.val[M31] * m2.val[M12]
+ m1.val[M32] * m2.val[M22] + m1.val[M33] * m2.val[M32];
float m33 = m1.val[M30] * m2.val[M03] + m1.val[M31] * m2.val[M13]
+ m1.val[M32] * m2.val[M23] + m1.val[M33] * m2.val[M33];
Matrix4 m = new Matrix4();
m.val[M00] = m00;
m.val[M10] = m10;
m.val[M20] = m20;
m.val[M30] = m30;
m.val[M01] = m01;
m.val[M11] = m11;
m.val[M21] = m21;
m.val[M31] = m31;
m.val[M02] = m02;
m.val[M12] = m12;
m.val[M22] = m22;
m.val[M32] = m32;
m.val[M03] = m03;
m.val[M13] = m13;
m.val[M23] = m23;
m.val[M33] = m33;
return m;
}
public FloatBuffer getAsFloatBuffer() {
return LSystem.base().support().newFloatBuffer(val, 0, val.length);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Matrix3) || o == null) {
return false;
}
if (this == o) {
return true;
}
Matrix3 comp = (Matrix3) o;
for (int i = 0; i < 16; i++) {
if (NumberUtils.compare(this.val[i], comp.val[i]) != 0) {
return false;
}
}
return true;
}
@Override
public float getX() {
return val[M13];
}
@Override
public float getY() {
return val[M03];
}
@Override
public int hashCode() {
int result = 17;
for (int j = 0; j < 16; j++) {
final long val = NumberUtils.floatToIntBits(this.val[j]);
result += 31 * result + (int) (val ^ (val >>> 32));
}
return result;
}
}