|
|
@ -0,0 +1,199 @@ |
|
|
|
import { EPSILON } from "../commons/types"; |
|
|
|
import { vec3, vec4 } from "."; |
|
|
|
|
|
|
|
|
|
|
|
export class Matrix4 { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @var 矩阵数据 |
|
|
|
*/ |
|
|
|
public values = new Float32Array(16); |
|
|
|
|
|
|
|
|
|
|
|
public constructor(values: number[] | null = null) { |
|
|
|
if (values) { |
|
|
|
this.setAll(values); |
|
|
|
} |
|
|
|
else { |
|
|
|
this.setIdentity(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过数组去设置矩阵 |
|
|
|
* @param values Array |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public setAll(values: number[]): Matrix4 { |
|
|
|
for (let i = 0; i < 16; i++) { |
|
|
|
this.values[i] = values[i]; |
|
|
|
} |
|
|
|
|
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过索引去设置矩阵 |
|
|
|
* @param index |
|
|
|
* @param value |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public setIndex(index: number, value: number): Matrix4 { |
|
|
|
if (index < 0 || index > 15) { |
|
|
|
throw new Error("Index out of bounds"); |
|
|
|
} |
|
|
|
this.values[index] = value; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过行和列去设置矩阵 |
|
|
|
* @param row |
|
|
|
* @param col |
|
|
|
* @param value |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public set(row: number, col: number, value: number): Matrix4 { |
|
|
|
let index: number = row * 4 + col; |
|
|
|
if (index < 0 || index > 15) { |
|
|
|
throw new Error("Index out of bounds"); |
|
|
|
} |
|
|
|
this.setIndex(index, value); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过索引来获取矩阵元素的值 |
|
|
|
* @param index |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public getIndex(index: number): number { |
|
|
|
if (index < 0 || index > 15) { |
|
|
|
throw new Error("Index out of bounds"); |
|
|
|
} |
|
|
|
return this.values[index]; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取矩阵的一行 |
|
|
|
* @param index |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public getRow(index: number): vec4 { |
|
|
|
let ret: vec4 = new vec4(); |
|
|
|
ret.r = this.get(index, 0); |
|
|
|
ret.g = this.get(index, 1); |
|
|
|
ret.b = this.get(index, 2); |
|
|
|
ret.a = this.get(index, 3); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取矩阵的一列 |
|
|
|
* @param index |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public getCol(index: number): vec4 { |
|
|
|
let ret: vec4 = new vec4(); |
|
|
|
ret.r = this.get(0, index); |
|
|
|
ret.g = this.get(1, index); |
|
|
|
ret.b = this.get(2, index); |
|
|
|
ret.a = this.get(3, index); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过行列号来获取矩阵元素的值 |
|
|
|
* @param row |
|
|
|
* @param col |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public get(row: number, col: number): number { |
|
|
|
let index: number = row * 4 + col; |
|
|
|
return this.getIndex(index); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 打印 |
|
|
|
*/ |
|
|
|
public print(): void { |
|
|
|
console.log(this.values[0] + " " + this.values[1] + " " + this.values[2] + " " + this.values[3]); |
|
|
|
console.log(this.values[4] + " " + this.values[5] + " " + this.values[6] + " " + this.values[6]); |
|
|
|
console.log(this.values[8] + " " + this.values[9] + " " + this.values[10] + " " + this.values[11]); |
|
|
|
console.log(this.values[12] + " " + this.values[13] + " " + this.values[14] + " " + this.values[15]); |
|
|
|
} |
|
|
|
/** |
|
|
|
* 设置成单位矩阵 |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public setIdentity(): Matrix4 { |
|
|
|
this.values[0] = 1; |
|
|
|
this.values[1] = 0; |
|
|
|
this.values[2] = 0; |
|
|
|
this.values[3] = 0; |
|
|
|
this.values[4] = 0; |
|
|
|
this.values[5] = 1; |
|
|
|
this.values[6] = 0; |
|
|
|
this.values[7] = 0; |
|
|
|
this.values[8] = 0; |
|
|
|
this.values[9] = 0; |
|
|
|
this.values[10] = 1; |
|
|
|
this.values[11] = 0; |
|
|
|
this.values[12] = 0; |
|
|
|
this.values[13] = 0; |
|
|
|
this.values[14] = 0; |
|
|
|
this.values[15] = 1; |
|
|
|
|
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 矩阵乘 |
|
|
|
* @param matrix |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public multiply(matrix: Matrix4): Matrix4 { |
|
|
|
|
|
|
|
for (let i = 0; i < 4; i++) { |
|
|
|
for(let j = 0; j < 4; j++){ |
|
|
|
let v1: vec4 = this.getRow() |
|
|
|
this.set(i,j, ) |
|
|
|
} |
|
|
|
} |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 生成一个投影矩阵 |
|
|
|
* @param left |
|
|
|
* @param right |
|
|
|
* @param bottom |
|
|
|
* @param top |
|
|
|
* @param near |
|
|
|
* @param far |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
public static orthographic(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4 { |
|
|
|
let ret: Matrix4 = new Matrix4(); |
|
|
|
|
|
|
|
let tm: Matrix4 = new Matrix4(); |
|
|
|
tm.set(0, 3, -(left + right) / 2); |
|
|
|
tm.set(1, 3, -(bottom + top) / 2); |
|
|
|
tm.set(2, 3, -(near + far) / 2); |
|
|
|
|
|
|
|
let sm: Matrix4 = new Matrix4(); |
|
|
|
sm.set(0, 0, 2 / (right - left)); |
|
|
|
sm.set(1, 2, 2 / (top - bottom)); |
|
|
|
sm.set(2, 2, 2 / (far - near)); |
|
|
|
|
|
|
|
let tzm: Matrix4 = new Matrix4(); |
|
|
|
tzm.set(2, 2, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |