1.2 update w/ GZDoom 4.9 features:

- Changeable player skins.
 - Ammo LEDs are now 1:1 with UT by using canvas textures.
 - Integrate some add-ons, including reskins.
 - Various fixes (some backported from Demolitionist).
 - Migrated from libeye to Gutamatics.
This commit is contained in:
Marisa the Magician 2022-11-05 23:59:16 +01:00
commit 602a89cc68
1761 changed files with 4461 additions and 1597 deletions

View file

@ -0,0 +1,319 @@
class dt_GM_Matrix4 {
double values[4][4];
/// Initialises a new Matrix4 in a static context.
static dt_GM_Matrix4 create() {
return new("dt_GM_Matrix4");
}
/// Returns an identity matrix.
static dt_GM_Matrix4 identity() {
let ret = dt_GM_Matrix4.create();
ret.values[0][0] = 1;
ret.values[1][1] = 1;
ret.values[2][2] = 1;
ret.values[3][3] = 1;
return ret;
}
/// Returns a rotation matrix from euler angles.
static dt_GM_Matrix4 fromEulerAngles(double yaw, double pitch, double roll) {
dt_GM_Matrix4 rYaw = dt_GM_Matrix4.identity();
double sYaw = sin(yaw);
double cYaw = cos(yaw);
rYaw.values[0][0] = cYaw;
rYaw.values[0][1] = -sYaw;
rYaw.values[1][0] = sYaw;
rYaw.values[1][1] = cYaw;
dt_GM_Matrix4 rPitch = dt_GM_Matrix4.identity();
double sPitch = sin(pitch);
double cPitch = cos(pitch);
rPitch.values[0][0] = cPitch;
rPitch.values[2][0] = -sPitch;
rPitch.values[0][2] = sPitch;
rPitch.values[2][2] = cPitch;
dt_GM_Matrix4 rRoll = dt_GM_Matrix4.identity();
double sRoll = sin(roll);
double cRoll = cos(roll);
rRoll.values[1][1] = cRoll;
rRoll.values[1][2] = -sRoll;
rRoll.values[2][1] = sRoll;
rRoll.values[2][2] = cRoll;
// concatenate ypr to get the final matrix
dt_GM_Matrix4 ret = rYaw.multiplyMatrix(rPitch);
ret = ret.multiplyMatrix(rRoll);
return ret;
}
/// Returns a rotation matrix from an axis and an angle.
static dt_GM_Matrix4 fromAxisAngle(Vector3 axis, double angle) {
dt_GM_Matrix4 ret = dt_GM_Matrix4.identity();
double c = cos(angle);
double s = sin(angle);
double x = axis.x;
double y = axis.y;
double z = axis.z;
ret.values[0][0] = (x * x * (1.0 - c) + c);
ret.values[0][1] = (x * y * (1.0 - c) - z * s);
ret.values[0][2] = (x * z * (1.0 - c) + y * s);
ret.values[1][0] = (y * x * (1.0 - c) + z * s);
ret.values[1][1] = (y * y * (1.0 - c) + c);
ret.values[1][2] = (y * z * (1.0 - c) - x * s);
ret.values[2][0] = (x * z * (1.0 - c) - y * s);
ret.values[2][1] = (y * z * (1.0 - c) + x * s);
ret.values[2][2] = (z * z * (1.0 - c) + c);
return ret;
}
/// Converts back from the rotation matrix to euler angles.
double, double, double rotationToEulerAngles() {
if (dt_GM_GlobalMaths.closeEnough(values[2][0], -1)) {
double x = 90;
double y = 0;
double z = atan2(values[0][1], values[0][2]);
return z, x, y;
}
else if (dt_GM_GlobalMaths.closeEnough(values[2][0], 1)) {
double x = -90;
double y = 0;
double z = atan2(-values[0][1], -values[0][2]);
return z, x, y;
}
else {
float x1 = -asin(values[2][0]);
float x2 = 180 - x1;
float y1 = atan2(values[2][1] / cos(x1), values[2][2] / cos(x1));
float y2 = atan2(values[2][1] / cos(x2), values[2][2] / cos(x2));
float z1 = atan2(values[1][0] / cos(x1), values[0][0] / cos(x1));
float z2 = atan2(values[1][0] / cos(x2), values[0][0] / cos(x2));
if ((abs(x1) + abs(y1) + abs(z1)) <= (abs(x2) + abs(y2) + abs(z2))) {
return z1, x1, y1;
}
else {
return z2, x2, y2;
}
}
}
static dt_GM_Matrix4 createTRSEuler(Vector3 translate, double yaw, double pitch, double roll, Vector3 scale) {
dt_GM_Matrix4 translateMat = dt_GM_Matrix4.identity();
translateMat.values[0][3] = translate.x;
translateMat.values[1][3] = translate.y;
translateMat.values[2][3] = translate.z;
dt_GM_Matrix4 rotateMat = dt_GM_Matrix4.fromEulerAngles(yaw, pitch, roll);
dt_GM_Matrix4 scaleMat = dt_GM_Matrix4.identity();
scaleMat.values[0][0] = scale.x;
scaleMat.values[1][1] = scale.y;
scaleMat.values[2][2] = scale.z;
dt_GM_Matrix4 ret = translateMat.multiplyMatrix(rotateMat);
ret = ret.multiplyMatrix(scaleMat);
return ret;
}
static dt_GM_Matrix4 createTRSAxisAngle(Vector3 translate, Vector3 axis, double angle, Vector3 scale) {
dt_GM_Matrix4 translateMat = dt_GM_Matrix4.identity();
translateMat.values[0][3] = translate.x;
translateMat.values[1][3] = translate.y;
translateMat.values[2][3] = translate.z;
dt_GM_Matrix4 rotateMat = dt_GM_Matrix4.fromAxisAngle(axis, angle);
dt_GM_Matrix4 scaleMat = dt_GM_Matrix4.identity();
scaleMat.values[0][0] = scale.x;
scaleMat.values[1][1] = scale.y;
scaleMat.values[2][2] = scale.z;
dt_GM_Matrix4 ret = translateMat.multiplyMatrix(rotateMat);
ret = ret.multiplyMatrix(scaleMat);
return ret;
}
/// Returns a view matrix.
static dt_GM_Matrix4 view(Vector3 camPos, double yaw, double pitch, double roll) {
// all of this is basically lifted and converted from PolyRenderer::SetupPerspectiveMatrix(),
// so credit goes to Graf Zahl/dpJudas/whoever else
// pitch needs to be adjusted by the pixel ratio
float pixelRatio = level.pixelstretch;
double angx = cos(pitch);
double angy = sin(pitch) * pixelRatio;
double alen = sqrt(angx * angx + angy * angy);
double adjustedPitch = asin(angy / alen);
double adjustedYaw = 90 - yaw;
// rotations
let cz = cos(roll);
let sz = sin(roll);
let cx = cos(adjustedPitch);
let sx = sin(adjustedPitch);
let cy = cos(adjustedYaw);
let sy = sin(adjustedYaw);
let rot = dt_GM_Matrix4.create();
rot.values[0][0] = cz * cy - sz * sx * sy;
rot.values[0][1] = -sz * cx;
rot.values[0][2] = cz * sy + sz * sx * cy;
rot.values[1][0] = sz * cy + cz * sx * sy;
rot.values[1][1] = cz * cx;
rot.values[1][2] = sz * sy - cz * sx * cy;
rot.values[2][0] = -cx * sy;
rot.values[2][1] = sx;
rot.values[2][2] = cx * cy;
rot.values[3][3] = 1.0;
// pixel ratio scaling
dt_GM_Matrix4 scale = dt_GM_Matrix4.identity();
scale.values[1][1] = pixelRatio;
// swapping y and z
dt_GM_Matrix4 swapYZ = dt_GM_Matrix4.create();
swapYZ.values[0][0] = 1;
swapYZ.values[1][2] = 1;
swapYZ.values[2][1] = -1;
swapYZ.values[3][3] = 1;
// translation
dt_GM_Matrix4 translate = dt_GM_Matrix4.identity();
translate.values[0][3] = -camPos.x;
translate.values[1][3] = -camPos.y;
translate.values[2][3] = -camPos.z;
// concatenate them all to get a final matrix
dt_GM_Matrix4 ret = rot.multiplyMatrix(scale);
ret = ret.multiplyMatrix(swapYZ);
ret = ret.multiplyMatrix(translate);
return ret;
}
/// Returns a perspective matrix (same format as gluPerspective).
static dt_GM_Matrix4 perspective(double fovy, double aspect, double zNear, double zFar) {
dt_GM_Matrix4 ret = dt_GM_Matrix4.create();
double f = 1 / tan(fovy / 2.0);
// x coord
ret.values[0][0] = f / aspect;
// y coord
ret.values[1][1] = f;
// z buffer coord
ret.values[2][2] = (zFar + zNear) / (zNear - zFar);
ret.values[2][3] = (2 * zFar * zNear) / (zNear - zFar);
// w (homogeneous coordinates)
ret.values[3][2] = -1;
return ret;
}
/// Returns a world->clip coords matrix from the passed args.
static dt_GM_Matrix4 worldToClip(Vector3 viewPos, double yaw, double pitch, double roll, double FOV) {
double aspect = Screen.getAspectRatio();
double fovy = dt_GM_GlobalMaths.fovHToY(FOV);
dt_GM_Matrix4 view = dt_GM_Matrix4.view(viewPos, yaw, pitch, roll);
// 5 & 65535 are what are used internally, so they're used here for consistency
dt_GM_Matrix4 perp = dt_GM_Matrix4.perspective(fovy, aspect, 5, 65535);
dt_GM_Matrix4 worldToClip = perp.multiplyMatrix(view);
return worldToClip;
}
/// Adds two matrices and returns the result.
dt_GM_Matrix4 addMatrix(dt_GM_Matrix4 other) const {
dt_GM_Matrix4 ret = dt_GM_Matrix4.create();
ret.values[0][0] = values[0][0] + other.values[0][0];
ret.values[0][1] = values[0][1] + other.values[0][1];
ret.values[0][2] = values[0][2] + other.values[0][2];
ret.values[0][3] = values[0][3] + other.values[0][3];
ret.values[1][0] = values[1][0] + other.values[1][0];
ret.values[1][1] = values[1][1] + other.values[1][1];
ret.values[1][2] = values[1][2] + other.values[1][2];
ret.values[1][3] = values[1][3] + other.values[1][3];
ret.values[2][0] = values[2][0] + other.values[2][0];
ret.values[2][1] = values[2][1] + other.values[2][1];
ret.values[2][2] = values[2][2] + other.values[2][2];
ret.values[2][3] = values[2][3] + other.values[2][3];
ret.values[3][0] = values[3][0] + other.values[3][0];
ret.values[3][1] = values[3][1] + other.values[3][1];
ret.values[3][2] = values[3][2] + other.values[3][2];
ret.values[3][3] = values[3][3] + other.values[3][3];
return ret;
}
/// Multiplies the matrix by a scalar and returns the result.
dt_GM_Matrix4 multiplyScalar(double scalar) const {
dt_GM_Matrix4 ret = dt_GM_Matrix4.create();
ret.values[0][0] = values[0][0] * scalar;
ret.values[0][1] = values[0][1] * scalar;
ret.values[0][2] = values[0][2] * scalar;
ret.values[0][3] = values[0][3] * scalar;
ret.values[1][0] = values[1][0] * scalar;
ret.values[1][1] = values[1][1] * scalar;
ret.values[1][2] = values[1][2] * scalar;
ret.values[1][3] = values[1][3] * scalar;
ret.values[2][0] = values[2][0] * scalar;
ret.values[2][1] = values[2][1] * scalar;
ret.values[2][2] = values[2][2] * scalar;
ret.values[2][3] = values[2][3] * scalar;
ret.values[3][0] = values[3][0] * scalar;
ret.values[3][1] = values[3][1] * scalar;
ret.values[3][2] = values[3][2] * scalar;
ret.values[3][3] = values[3][3] * scalar;
return ret;
}
/// Multiplies two matrices and returns the result.
dt_GM_Matrix4 multiplyMatrix(dt_GM_Matrix4 other) const {
dt_GM_Matrix4 ret = dt_GM_Matrix4.create();
for (int row = 0; row < 4; row++) {
ret.values[row][0] =
values[row][0] * other.values[0][0] +
values[row][1] * other.values[1][0] +
values[row][2] * other.values[2][0] +
values[row][3] * other.values[3][0];
ret.values[row][1] =
values[row][0] * other.values[0][1] +
values[row][1] * other.values[1][1] +
values[row][2] * other.values[2][1] +
values[row][3] * other.values[3][1];
ret.values[row][2] =
values[row][0] * other.values[0][2] +
values[row][1] * other.values[1][2] +
values[row][2] * other.values[2][2] +
values[row][3] * other.values[3][2];
ret.values[row][3] =
values[row][0] * other.values[0][3] +
values[row][1] * other.values[1][3] +
values[row][2] * other.values[2][3] +
values[row][3] * other.values[3][3];
}
return ret;
}
/// Multiplies this Matrix by a 3D vector.
Vector3 multiplyVector3(Vector3 vec, dt_GM_VectorType type = dt_GM_Vector_Position, bool divideW = true) const {
let vecW = (type == dt_GM_Vector_Position) ? 1.0 : 0.0;
let ret = (
values[0][0] * vec.x + values[0][1] * vec.y + values[0][2] * vec.z + values[0][3] * vecW,
values[1][0] * vec.x + values[1][1] * vec.y + values[1][2] * vec.z + values[1][3] * vecW,
values[2][0] * vec.x + values[2][1] * vec.y + values[2][2] * vec.z + values[2][3] * vecW
);
if (divideW) {
let retW = values[3][0] * vec.x + values[3][1] * vec.y + values[3][2] * vec.z + values[3][3] * vecW;
ret /= retW;
}
return ret;
}
}