oktaeder/src/data/Matrix4x4.ts
2023-07-29 02:01:22 +02:00

246 lines
5.5 KiB
TypeScript

/*!
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/.
*/
import { QuaternionObject, Vector3Object } from ".";
export interface Matrix4x4Object {
readonly ix: number;
readonly iy: number;
readonly iz: number;
readonly iw: number;
readonly jx: number;
readonly jy: number;
readonly jz: number;
readonly jw: number;
readonly kx: number;
readonly ky: number;
readonly kz: number;
readonly kw: number;
readonly tx: number;
readonly ty: number;
readonly tz: number;
readonly tw: number;
}
export type Matrix4x4Tuple = readonly [
ix: number, iy: number, iz: number, iw: number,
jx: number, jy: number, jz: number, jw: number,
kx: number, ky: number, kz: number, kw: number,
tx: number, ty: number, tz: number, tw: number,
];
export class Matrix4x4 {
readonly type!: "Matrix4x4";
ix: number;
iy: number;
iz: number;
iw: number;
jx: number;
jy: number;
jz: number;
jw: number;
kx: number;
ky: number;
kz: number;
kw: number;
tx: number;
ty: number;
tz: number;
tw: number;
constructor(
ix: number, iy: number, iz: number, iw: number,
jx: number, jy: number, jz: number, jw: number,
kx: number, ky: number, kz: number, kw: number,
tx: number, ty: number, tz: number, tw: number
) {
this.ix = ix;
this.iy = iy;
this.iz = iz;
this.iw = iw;
this.jx = jx;
this.jy = jy;
this.jz = jz;
this.jw = jw;
this.kx = kx;
this.ky = ky;
this.kz = kz;
this.kw = kw;
this.tx = tx;
this.ty = ty;
this.tz = tz;
this.tw = tw;
}
static fromObject(object: Matrix4x4Object): Matrix4x4 {
return new Matrix4x4(
object.ix, object.iy, object.iz, object.iw,
object.jx, object.jy, object.jz, object.jw,
object.kx, object.ky, object.kz, object.kw,
object.tx, object.ty, object.tz, object.tw,
);
}
static fromTuple(tuple: Matrix4x4Tuple): Matrix4x4 {
return new Matrix4x4(...tuple);
}
static fromTranslation(translation: Vector3Object): Matrix4x4 {
return new Matrix4x4(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
translation.x, translation.y, translation.z, 1,
);
}
static fromQuaternion(quaternion: QuaternionObject): Matrix4x4 {
const xx = quaternion.x * quaternion.x;
const xy = quaternion.x * quaternion.y;
const xz = quaternion.x * quaternion.z;
const xw = quaternion.x * quaternion.w;
const yy = quaternion.y * quaternion.y;
const yz = quaternion.y * quaternion.z;
const yw = quaternion.y * quaternion.w;
const zz = quaternion.z * quaternion.z;
const zw = quaternion.z * quaternion.w;
return new Matrix4x4(
1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0,
2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0,
2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0,
0, 0, 0, 1,
);
}
static fromScale(scale: Vector3Object): Matrix4x4 {
return new Matrix4x4(
scale.x, 0, 0, 0,
0, scale.y, 0, 0,
0, 0, scale.z, 0,
0, 0, 0, 1
);
}
setObject(object: Matrix4x4Object): Matrix4x4 {
this.ix = object.ix;
this.iy = object.iy;
this.iz = object.iz;
this.iw = object.iw;
this.jx = object.jx;
this.jy = object.jy;
this.jz = object.jz;
this.jw = object.jw;
this.kx = object.kx;
this.ky = object.ky;
this.kz = object.kz;
this.kw = object.kw;
this.tx = object.tx;
this.ty = object.ty;
this.tz = object.tz;
this.tw = object.tw;
return this;
}
setTuple(tuple: Matrix4x4Tuple): Matrix4x4 {
this.ix = tuple[0];
this.iy = tuple[1];
this.iz = tuple[2];
this.iw = tuple[3];
this.jx = tuple[4];
this.jy = tuple[5];
this.jz = tuple[6];
this.jw = tuple[7];
this.kx = tuple[8];
this.ky = tuple[9];
this.kz = tuple[10];
this.kw = tuple[11];
this.tx = tuple[12];
this.ty = tuple[13];
this.tz = tuple[14];
this.tw = tuple[15];
return this;
}
setTranslation(translation: Vector3Object): Matrix4x4 {
this.ix = 1;
this.iy = 0;
this.iz = 0;
this.iw = 0;
this.jx = 0;
this.jy = 1;
this.jz = 0;
this.jw = 0;
this.kx = 0;
this.ky = 0;
this.kz = 1;
this.kw = 0;
this.tx = translation.x;
this.ty = translation.y;
this.tz = translation.z;
this.tw = 1;
return this;
}
setQuaternion(quaternion: QuaternionObject): Matrix4x4 {
const xx = quaternion.x * quaternion.x;
const xy = quaternion.x * quaternion.y;
const xz = quaternion.x * quaternion.z;
const xw = quaternion.x * quaternion.w;
const yy = quaternion.y * quaternion.y;
const yz = quaternion.y * quaternion.z;
const yw = quaternion.y * quaternion.w;
const zz = quaternion.z * quaternion.z;
const zw = quaternion.z * quaternion.w;
this.ix = 1 - 2 * (yy + zz);
this.iy = 2 * (xy + zw);
this.iz = 2 * (xz - yw);
this.iw = 0;
this.jx = 2 * (xy - zw);
this.jy = 1 - 2 * (xx + zz);
this.jz = 2 * (yz + xw);
this.jw = 0;
this.kx = 2 * (xz + yw);
this.ky = 2 * (yz - xw);
this.kz = 1 - 2 * (xx + yy);
this.kw = 0;
this.tx = 0;
this.ty = 0;
this.tz = 0;
this.tw = 1;
return this;
}
setScale(scale: Vector3Object): Matrix4x4 {
this.ix = scale.x;
this.iy = 0;
this.iz = 0;
this.iw = 0;
this.jx = 0;
this.jy = scale.y;
this.jz = 0;
this.jw = 0;
this.kx = 0;
this.ky = 0;
this.kz = scale.z;
this.kw = 0;
this.tx = 0;
this.ty = 0;
this.tz = 0;
this.tw = 1;
return this;
}
}
Object.defineProperty(Matrix4x4.prototype, "type", { value: "Matrix4x4" });
export function isMatrix4x4(value: unknown): value is Matrix4x4 {
return Boolean(value) && (value as Matrix4x4).type === "Matrix4x4";
}