114 lines
3.0 KiB
TypeScript
114 lines
3.0 KiB
TypeScript
// @ts-ignore
|
|
import { Matrix, Vector } from 'sylvester.js';
|
|
|
|
const $M = Matrix.create;
|
|
|
|
// augment Sylvester some
|
|
Matrix.Translation = function(v: Matrix): Matrix {
|
|
if (v.elements.length === 2) {
|
|
const r = Matrix.I(3);
|
|
r.elements[2][0] = v.elements[0];
|
|
r.elements[2][1] = v.elements[1];
|
|
return r;
|
|
}
|
|
|
|
if (v.elements.length === 3) {
|
|
const r = Matrix.I(4);
|
|
r.elements[0][3] = v.elements[0];
|
|
r.elements[1][3] = v.elements[1];
|
|
r.elements[2][3] = v.elements[2];
|
|
return r;
|
|
}
|
|
|
|
throw Error('Invalid length for Translation');
|
|
};
|
|
|
|
Matrix.prototype.flatten = function(): number[] {
|
|
const result = [];
|
|
/* tslint:disable: no-invalid-this prefer-for-of */
|
|
if (this.elements.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
for (let j = 0; j < this.elements[0].length; j++) {
|
|
for (let i = 0; i < this.elements.length; i++) {
|
|
result.push(this.elements[i][j]);
|
|
}
|
|
}
|
|
/* tslint:enable */
|
|
return result;
|
|
};
|
|
|
|
Matrix.prototype.ensure4x4 = function(): Matrix | null {
|
|
/* tslint:disable: no-invalid-this */
|
|
if (this.elements.length === 4 && this.elements[0].length === 4) {
|
|
return this;
|
|
}
|
|
|
|
if (this.elements.length > 4 || this.elements[0].length > 4) {
|
|
return null;
|
|
}
|
|
|
|
for (let i = 0; i < this.elements.length; i++) {
|
|
for (let j = this.elements[i].length; j < 4; j++) {
|
|
if (i === j) {
|
|
this.elements[i].push(1);
|
|
} else {
|
|
this.elements[i].push(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (let i = this.elements.length; i < 4; i++) {
|
|
if (i === 0) {
|
|
this.elements.push([1, 0, 0, 0]);
|
|
} else if (i === 1) {
|
|
this.elements.push([0, 1, 0, 0]);
|
|
} else if (i === 2) {
|
|
this.elements.push([0, 0, 1, 0]);
|
|
} else if (i === 3) {
|
|
this.elements.push([0, 0, 0, 1]);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
/* tslint:enable */
|
|
};
|
|
|
|
Vector.prototype.flatten = function(): number[] {
|
|
/* tslint:disable: no-invalid-this */
|
|
return this.elements;
|
|
/* tslint:enable */
|
|
};
|
|
|
|
//
|
|
// gluPerspective
|
|
//
|
|
export function makePerspective(fovy: number, aspect: number, znear: number, zfar: number): Matrix {
|
|
const ymax = znear * Math.tan(fovy * Math.PI / 360.0);
|
|
const ymin = -ymax;
|
|
const xmin = ymin * aspect;
|
|
const xmax = ymax * aspect;
|
|
|
|
return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
|
|
}
|
|
|
|
//
|
|
// glFrustum
|
|
//
|
|
function makeFrustum(left: number, right: number,
|
|
bottom: number, top: number,
|
|
znear: number, zfar: number): Matrix {
|
|
const X = 2 * znear / (right - left);
|
|
const Y = 2 * znear / (top - bottom);
|
|
const A = (right + left) / (right - left);
|
|
const B = (top + bottom) / (top - bottom);
|
|
const C = -(zfar + znear) / (zfar - znear);
|
|
const D = -2 * zfar * znear / (zfar - znear);
|
|
|
|
return $M([[X, 0, A, 0],
|
|
[0, Y, B, 0],
|
|
[0, 0, C, D],
|
|
[0, 0, -1, 0]]);
|
|
}
|