|
@@ -77,7 +77,7 @@ export namespace Mat4 {
|
|
|
mat[15] = 1;
|
|
|
return mat;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
export function ofRows(rows: number[][]): Mat4 {
|
|
|
const out = zero();
|
|
|
for (let i = 0; i < 4; i++) {
|
|
@@ -463,6 +463,165 @@ export namespace Mat4 {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Generates a frustum matrix with the given bounds
|
|
|
+ */
|
|
|
+ export function frustum(out: Mat4, left: number, right: number, bottom: number, top: number, near: number, far: number) {
|
|
|
+ let rl = 1 / (right - left);
|
|
|
+ let tb = 1 / (top - bottom);
|
|
|
+ let nf = 1 / (near - far);
|
|
|
+ out[0] = (near * 2) * rl;
|
|
|
+ out[1] = 0;
|
|
|
+ out[2] = 0;
|
|
|
+ out[3] = 0;
|
|
|
+ out[4] = 0;
|
|
|
+ out[5] = (near * 2) * tb;
|
|
|
+ out[6] = 0;
|
|
|
+ out[7] = 0;
|
|
|
+ out[8] = (right + left) * rl;
|
|
|
+ out[9] = (top + bottom) * tb;
|
|
|
+ out[10] = (far + near) * nf;
|
|
|
+ out[11] = -1;
|
|
|
+ out[12] = 0;
|
|
|
+ out[13] = 0;
|
|
|
+ out[14] = (far * near * 2) * nf;
|
|
|
+ out[15] = 0;
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Generates a perspective projection matrix with the given bounds
|
|
|
+ */
|
|
|
+ export function perspective(out: Mat4, fovy: number, aspect: number, near: number, far: number) {
|
|
|
+ let f = 1.0 / Math.tan(fovy / 2);
|
|
|
+ let nf = 1 / (near - far);
|
|
|
+ out[0] = f / aspect;
|
|
|
+ out[1] = 0;
|
|
|
+ out[2] = 0;
|
|
|
+ out[3] = 0;
|
|
|
+ out[4] = 0;
|
|
|
+ out[5] = f;
|
|
|
+ out[6] = 0;
|
|
|
+ out[7] = 0;
|
|
|
+ out[8] = 0;
|
|
|
+ out[9] = 0;
|
|
|
+ out[10] = (far + near) * nf;
|
|
|
+ out[11] = -1;
|
|
|
+ out[12] = 0;
|
|
|
+ out[13] = 0;
|
|
|
+ out[14] = (2 * far * near) * nf;
|
|
|
+ out[15] = 0;
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Generates a orthogonal projection matrix with the given bounds
|
|
|
+ */
|
|
|
+ export function ortho(out: Mat4, left: number, right: number, bottom: number, top: number, near: number, far: number) {
|
|
|
+ let lr = 1 / (left - right);
|
|
|
+ let bt = 1 / (bottom - top);
|
|
|
+ let nf = 1 / (near - far);
|
|
|
+ out[0] = -2 * lr;
|
|
|
+ out[1] = 0;
|
|
|
+ out[2] = 0;
|
|
|
+ out[3] = 0;
|
|
|
+ out[4] = 0;
|
|
|
+ out[5] = -2 * bt;
|
|
|
+ out[6] = 0;
|
|
|
+ out[7] = 0;
|
|
|
+ out[8] = 0;
|
|
|
+ out[9] = 0;
|
|
|
+ out[10] = 2 * nf;
|
|
|
+ out[11] = 0;
|
|
|
+ out[12] = (left + right) * lr;
|
|
|
+ out[13] = (top + bottom) * bt;
|
|
|
+ out[14] = (far + near) * nf;
|
|
|
+ out[15] = 1;
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Generates a look-at matrix with the given eye position, focal point, and up axis
|
|
|
+ */
|
|
|
+ export function lookAt(out: Mat4, eye: Vec3, center: Vec3, up: Vec3) {
|
|
|
+ let x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
|
|
|
+ let eyex = eye[0];
|
|
|
+ let eyey = eye[1];
|
|
|
+ let eyez = eye[2];
|
|
|
+ let upx = up[0];
|
|
|
+ let upy = up[1];
|
|
|
+ let upz = up[2];
|
|
|
+ let centerx = center[0];
|
|
|
+ let centery = center[1];
|
|
|
+ let centerz = center[2];
|
|
|
+
|
|
|
+ if (Math.abs(eyex - centerx) < EPSILON.Value &&
|
|
|
+ Math.abs(eyey - centery) < EPSILON.Value &&
|
|
|
+ Math.abs(eyez - centerz) < EPSILON.Value
|
|
|
+ ) {
|
|
|
+ return setIdentity(out);
|
|
|
+ }
|
|
|
+
|
|
|
+ z0 = eyex - centerx;
|
|
|
+ z1 = eyey - centery;
|
|
|
+ z2 = eyez - centerz;
|
|
|
+
|
|
|
+ len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
|
|
|
+ z0 *= len;
|
|
|
+ z1 *= len;
|
|
|
+ z2 *= len;
|
|
|
+
|
|
|
+ x0 = upy * z2 - upz * z1;
|
|
|
+ x1 = upz * z0 - upx * z2;
|
|
|
+ x2 = upx * z1 - upy * z0;
|
|
|
+ len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
|
|
|
+ if (!len) {
|
|
|
+ x0 = 0;
|
|
|
+ x1 = 0;
|
|
|
+ x2 = 0;
|
|
|
+ } else {
|
|
|
+ len = 1 / len;
|
|
|
+ x0 *= len;
|
|
|
+ x1 *= len;
|
|
|
+ x2 *= len;
|
|
|
+ }
|
|
|
+
|
|
|
+ y0 = z1 * x2 - z2 * x1;
|
|
|
+ y1 = z2 * x0 - z0 * x2;
|
|
|
+ y2 = z0 * x1 - z1 * x0;
|
|
|
+
|
|
|
+ len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
|
|
|
+ if (!len) {
|
|
|
+ y0 = 0;
|
|
|
+ y1 = 0;
|
|
|
+ y2 = 0;
|
|
|
+ } else {
|
|
|
+ len = 1 / len;
|
|
|
+ y0 *= len;
|
|
|
+ y1 *= len;
|
|
|
+ y2 *= len;
|
|
|
+ }
|
|
|
+
|
|
|
+ out[0] = x0;
|
|
|
+ out[1] = y0;
|
|
|
+ out[2] = z0;
|
|
|
+ out[3] = 0;
|
|
|
+ out[4] = x1;
|
|
|
+ out[5] = y1;
|
|
|
+ out[6] = z1;
|
|
|
+ out[7] = 0;
|
|
|
+ out[8] = x2;
|
|
|
+ out[9] = y2;
|
|
|
+ out[10] = z2;
|
|
|
+ out[11] = 0;
|
|
|
+ out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
|
|
|
+ out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
|
|
|
+ out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
|
|
|
+ out[15] = 1;
|
|
|
+
|
|
|
+ return out;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export namespace Vec3 {
|