blobt
4 years ago
3 changed files with 535 additions and 0 deletions
@ -0,0 +1,396 @@ |
|||||
|
import { EPSILON } from "../common"; |
||||
|
import { vec3, vec4 } from "."; |
||||
|
|
||||
|
export class mat4 { |
||||
|
|
||||
|
public values = new Float32Array(16); |
||||
|
|
||||
|
public constructor(values: number[] | null = null) { |
||||
|
if (values) { |
||||
|
this.set(values); |
||||
|
} |
||||
|
else { |
||||
|
this.setIdentity(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public set(values: number[]): mat4 { |
||||
|
for (let i = 0; i < 16; i++) { |
||||
|
this.values[i] = values[i]; |
||||
|
} |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public at(index: number): number { |
||||
|
return this.values[index]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 复制当前矩阵到目标矩阵 |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public copy(dest: mat4 | null = null): mat4 { |
||||
|
if (!dest) dest = new mat4(); |
||||
|
|
||||
|
for (let i = 0; i < 16; i++) { |
||||
|
dest.values[i] = this.values[i]; |
||||
|
} |
||||
|
|
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断矩阵是否相等 |
||||
|
* @param matrix |
||||
|
* @param threshold |
||||
|
* @returns |
||||
|
*/ |
||||
|
public equals(matrix: mat4, threshold = EPSILON): boolean { |
||||
|
for (let i = 0; i < 16; i++) { |
||||
|
if (Math.abs(this.values[i] - matrix.at(i)) > threshold) |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取一行 |
||||
|
* @param index |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getRow(index: number, dest: vec4 | null = null): vec4 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec4(); |
||||
|
} |
||||
|
dest.x = this.values[index * 4 + 0], |
||||
|
dest.y = this.values[index * 4 + 1], |
||||
|
dest.z = this.values[index * 4 + 2], |
||||
|
dest.w = this.values[index * 4 + 3] |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取一列 |
||||
|
* @param index |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getColumn(index: number, dest: vec4 | null = null): vec4 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec4(); |
||||
|
} |
||||
|
dest.x = this.values[index]; |
||||
|
dest.y = this.values[index + 4]; |
||||
|
dest.z = this.values[index + 8]; |
||||
|
dest.w = this.values[index + 12]; |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getPosition(dest: vec3 | null = null): vec3 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec3(); |
||||
|
} |
||||
|
dest.x = this.values[12]; |
||||
|
dest.y = this.values[13]; |
||||
|
dest.z = this.values[14]; |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取x轴 |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getXAxis(dest: vec3 | null = null): vec3 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec3(); |
||||
|
} |
||||
|
dest.x = this.values[0]; |
||||
|
dest.y = this.values[1]; |
||||
|
dest.z = this.values[2]; |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取y轴 |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getYAxis(dest: vec3 | null = null): vec3 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec3(); |
||||
|
} |
||||
|
dest.x = this.values[4]; |
||||
|
dest.y = this.values[5]; |
||||
|
dest.z = this.values[6]; |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取z轴 |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getZAxis(dest: vec3 | null = null): vec3 { |
||||
|
if (dest === null) { |
||||
|
dest = new vec3(); |
||||
|
} |
||||
|
dest.x = this.values[8]; |
||||
|
dest.y = this.values[9]; |
||||
|
dest.z = this.values[10]; |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param idx |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public getAxis(idx: number, dest: vec3 | null = null): vec3 { |
||||
|
if (idx === 0) { |
||||
|
return this.getXAxis(dest); |
||||
|
} else if (idx === 1) { |
||||
|
return this.getYAxis(dest); |
||||
|
} else { |
||||
|
return this.getZAxis(dest); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置成单位矩阵 |
||||
|
* @returns |
||||
|
*/ |
||||
|
public setIdentity(): mat4 { |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转置 |
||||
|
* @returns |
||||
|
*/ |
||||
|
public transpose(): mat4 { |
||||
|
let temp01 = this.values[1], temp02 = this.values[2], |
||||
|
temp03 = this.values[3], temp12 = this.values[6], |
||||
|
temp13 = this.values[7], temp23 = this.values[11]; |
||||
|
|
||||
|
this.values[1] = this.values[4]; |
||||
|
this.values[2] = this.values[8]; |
||||
|
this.values[3] = this.values[12]; |
||||
|
this.values[4] = temp01; |
||||
|
|
||||
|
this.values[6] = this.values[9]; |
||||
|
this.values[7] = this.values[13]; |
||||
|
this.values[8] = temp02; |
||||
|
this.values[9] = temp12; |
||||
|
this.values[11] = this.values[14]; |
||||
|
this.values[12] = temp03; |
||||
|
this.values[13] = temp13; |
||||
|
this.values[14] = temp23; |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取矩阵行列式 |
||||
|
* @returns |
||||
|
*/ |
||||
|
public determinant(): number { |
||||
|
let a00 = this.values[0], a01 = this.values[1], a02 = this.values[2], a03 = this.values[3], |
||||
|
a10 = this.values[4], a11 = this.values[5], a12 = this.values[6], a13 = this.values[7], |
||||
|
a20 = this.values[8], a21 = this.values[9], a22 = this.values[10], a23 = this.values[11], |
||||
|
a30 = this.values[12], a31 = this.values[13], a32 = this.values[14], a33 = this.values[15]; |
||||
|
|
||||
|
let det00 = a00 * a11 - a01 * a10, |
||||
|
det01 = a00 * a12 - a02 * a10, |
||||
|
det02 = a00 * a13 - a03 * a10, |
||||
|
det03 = a01 * a12 - a02 * a11, |
||||
|
det04 = a01 * a13 - a03 * a11, |
||||
|
det05 = a02 * a13 - a03 * a12, |
||||
|
det06 = a20 * a31 - a21 * a30, |
||||
|
det07 = a20 * a32 - a22 * a30, |
||||
|
det08 = a20 * a33 - a23 * a30, |
||||
|
det09 = a21 * a32 - a22 * a31, |
||||
|
det10 = a21 * a33 - a23 * a31, |
||||
|
det11 = a22 * a33 - a23 * a32; |
||||
|
|
||||
|
return (det00 * det11 - det01 * det10 + det02 * det09 + det03 * det08 - det04 * det07 + det05 * det06); |
||||
|
} |
||||
|
|
||||
|
public det(): number { |
||||
|
return this.determinant(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 逆矩阵 |
||||
|
* @param out |
||||
|
* @returns |
||||
|
*/ |
||||
|
public inverse(out: mat4): boolean { |
||||
|
this.copy(out); |
||||
|
let a00 = out.values[0], a01 = out.values[1], a02 = out.values[2], a03 = out.values[3], |
||||
|
a10 = out.values[4], a11 = out.values[5], a12 = out.values[6], a13 = out.values[7], |
||||
|
a20 = out.values[8], a21 = out.values[9], a22 = out.values[10], a23 = out.values[11], |
||||
|
a30 = out.values[12], a31 = out.values[13], a32 = out.values[14], a33 = out.values[15]; |
||||
|
|
||||
|
let det00 = a00 * a11 - a01 * a10, |
||||
|
det01 = a00 * a12 - a02 * a10, |
||||
|
det02 = a00 * a13 - a03 * a10, |
||||
|
det03 = a01 * a12 - a02 * a11, |
||||
|
det04 = a01 * a13 - a03 * a11, |
||||
|
det05 = a02 * a13 - a03 * a12, |
||||
|
det06 = a20 * a31 - a21 * a30, |
||||
|
det07 = a20 * a32 - a22 * a30, |
||||
|
det08 = a20 * a33 - a23 * a30, |
||||
|
det09 = a21 * a32 - a22 * a31, |
||||
|
det10 = a21 * a33 - a23 * a31, |
||||
|
det11 = a22 * a33 - a23 * a32; |
||||
|
|
||||
|
let det = (det00 * det11 - det01 * det10 + det02 * det09 + det03 * det08 - det04 * det07 + det05 * det06); |
||||
|
|
||||
|
if (!det) |
||||
|
return false; |
||||
|
|
||||
|
det = 1.0 / det; |
||||
|
|
||||
|
out.values[0] = (a11 * det11 - a12 * det10 + a13 * det09) * det; |
||||
|
out.values[1] = (-a01 * det11 + a02 * det10 - a03 * det09) * det; |
||||
|
out.values[2] = (a31 * det05 - a32 * det04 + a33 * det03) * det; |
||||
|
out.values[3] = (-a21 * det05 + a22 * det04 - a23 * det03) * det; |
||||
|
out.values[4] = (-a10 * det11 + a12 * det08 - a13 * det07) * det; |
||||
|
out.values[5] = (a00 * det11 - a02 * det08 + a03 * det07) * det; |
||||
|
out.values[6] = (-a30 * det05 + a32 * det02 - a33 * det01) * det; |
||||
|
out.values[7] = (a20 * det05 - a22 * det02 + a23 * det01) * det; |
||||
|
out.values[8] = (a10 * det10 - a11 * det08 + a13 * det06) * det; |
||||
|
out.values[9] = (-a00 * det10 + a01 * det08 - a03 * det06) * det; |
||||
|
out.values[10] = (a30 * det04 - a31 * det02 + a33 * det00) * det; |
||||
|
out.values[11] = (-a20 * det04 + a21 * det02 - a23 * det00) * det; |
||||
|
out.values[12] = (-a10 * det09 + a11 * det07 - a12 * det06) * det; |
||||
|
out.values[13] = (a00 * det09 - a01 * det07 + a02 * det06) * det; |
||||
|
out.values[14] = (-a30 * det03 + a31 * det01 - a32 * det00) * det; |
||||
|
out.values[15] = (a20 * det03 - a21 * det01 + a22 * det00) * det; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 矩阵相乘 |
||||
|
* @param matrix |
||||
|
* @returns |
||||
|
*/ |
||||
|
public multiply(matrix: mat4): mat4 { |
||||
|
let a00 = this.values[0], a01 = this.values[1], a02 = this.values[2], a03 = this.values[3]; |
||||
|
let a10 = this.values[4], a11 = this.values[5], a12 = this.values[6], a13 = this.values[7]; |
||||
|
let a20 = this.values[8], a21 = this.values[9], a22 = this.values[10], a23 = this.values[11]; |
||||
|
let a30 = this.values[12], a31 = this.values[13], a32 = this.values[14], a33 = this.values[15]; |
||||
|
|
||||
|
let b0 = matrix.at(0), |
||||
|
b1 = matrix.at(1), |
||||
|
b2 = matrix.at(2), |
||||
|
b3 = matrix.at(3); |
||||
|
|
||||
|
this.values[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; |
||||
|
this.values[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; |
||||
|
this.values[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; |
||||
|
this.values[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; |
||||
|
|
||||
|
b0 = matrix.at(4); |
||||
|
b1 = matrix.at(5); |
||||
|
b2 = matrix.at(6); |
||||
|
b3 = matrix.at(7); |
||||
|
|
||||
|
this.values[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; |
||||
|
this.values[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; |
||||
|
this.values[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; |
||||
|
this.values[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; |
||||
|
|
||||
|
b0 = matrix.at(8); |
||||
|
b1 = matrix.at(9); |
||||
|
b2 = matrix.at(10); |
||||
|
b3 = matrix.at(11); |
||||
|
|
||||
|
this.values[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; |
||||
|
this.values[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; |
||||
|
this.values[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; |
||||
|
this.values[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; |
||||
|
|
||||
|
b0 = matrix.at(12); |
||||
|
b1 = matrix.at(13); |
||||
|
b2 = matrix.at(14); |
||||
|
b3 = matrix.at(15); |
||||
|
|
||||
|
this.values[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; |
||||
|
this.values[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; |
||||
|
this.values[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; |
||||
|
this.values[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 矩阵乘以3维度向量 |
||||
|
* @param vector |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public multiplyVec3(vector: vec3, dest: vec3 | null = null): vec3 { |
||||
|
if (!dest) dest = new vec3(); |
||||
|
let x = vector.x, |
||||
|
y = vector.y, |
||||
|
z = vector.z; |
||||
|
|
||||
|
dest.x = this.values[0] * x + this.values[4] * y + this.values[8] * z + this.values[12]; |
||||
|
dest.y = this.values[1] * x + this.values[5] * y + this.values[9] * z + this.values[13]; |
||||
|
dest.z = this.values[2] * x + this.values[6] * y + this.values[10] * z + this.values[14]; |
||||
|
|
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 矩阵乘4维向量 |
||||
|
* @param vector |
||||
|
* @param dest |
||||
|
* @returns |
||||
|
*/ |
||||
|
public multiplyVec4(vector: vec4, dest: vec4 | null = null): vec4 { |
||||
|
if (!dest) dest = new vec4(); |
||||
|
|
||||
|
let x = vector.x, |
||||
|
y = vector.y, |
||||
|
z = vector.z, |
||||
|
w = vector.w; |
||||
|
|
||||
|
dest.x = this.values[0] * x + this.values[4] * y + this.values[8] * z + this.values[12] * w; |
||||
|
dest.y = this.values[1] * x + this.values[5] * y + this.values[9] * z + this.values[13] * w; |
||||
|
dest.z = this.values[2] * x + this.values[6] * y + this.values[10] * z + this.values[14] * w; |
||||
|
dest.w = this.values[3] * x + this.values[7] * y + this.values[11] * z + this.values[15] * w; |
||||
|
|
||||
|
return dest; |
||||
|
} |
||||
|
} |
@ -0,0 +1,136 @@ |
|||||
|
import { EPSILON } from "../common"; |
||||
|
import { vec3 } from "./Vec3"; |
||||
|
|
||||
|
export class vec4 { |
||||
|
|
||||
|
public values = new Float32Array(4); |
||||
|
|
||||
|
public get x(): number { |
||||
|
return this.values[0]; |
||||
|
} |
||||
|
|
||||
|
public get y(): number { |
||||
|
return this.values[1]; |
||||
|
} |
||||
|
|
||||
|
public get z(): number { |
||||
|
return this.values[2]; |
||||
|
} |
||||
|
|
||||
|
public get w(): number { |
||||
|
return this.values[3]; |
||||
|
} |
||||
|
|
||||
|
public set x(value: number) { |
||||
|
this.values[0] = value; |
||||
|
} |
||||
|
|
||||
|
public set y(value: number) { |
||||
|
this.values[1] = value; |
||||
|
} |
||||
|
|
||||
|
public set z(value: number) { |
||||
|
this.values[2] = value; |
||||
|
} |
||||
|
|
||||
|
public set w(value: number) { |
||||
|
this.values[3] = value; |
||||
|
} |
||||
|
|
||||
|
public get vec3(): vec3 { |
||||
|
return new vec3([this.x, this.y, this.z]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* RGBA |
||||
|
*/ |
||||
|
public get r(): number { |
||||
|
return this.values[0]; |
||||
|
} |
||||
|
|
||||
|
public get g(): number { |
||||
|
return this.values[1]; |
||||
|
} |
||||
|
|
||||
|
public get b(): number { |
||||
|
return this.values[2]; |
||||
|
} |
||||
|
|
||||
|
public get a(): number { |
||||
|
return this.values[3]; |
||||
|
} |
||||
|
|
||||
|
public set r(value: number) { |
||||
|
this.values[0] = value; |
||||
|
} |
||||
|
|
||||
|
public set g(value: number) { |
||||
|
this.values[1] = value; |
||||
|
} |
||||
|
|
||||
|
public set b(value: number) { |
||||
|
this.values[2] = value; |
||||
|
} |
||||
|
|
||||
|
public set a(value: number) { |
||||
|
this.values[3] = value; |
||||
|
} |
||||
|
|
||||
|
public constructor(values: number[] | null = null) { |
||||
|
if (values) { |
||||
|
this.x = values[0]; |
||||
|
this.y = values[1]; |
||||
|
this.z = values[2]; |
||||
|
this.w = values[3]; |
||||
|
} else { |
||||
|
this.x = this.y = this.z = this.w = 0.0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public at(index: number): number { |
||||
|
return this.values[index]; |
||||
|
} |
||||
|
|
||||
|
public reset(): void { |
||||
|
this.x = 0; |
||||
|
this.y = 0; |
||||
|
this.z = 0; |
||||
|
this.w = 0; |
||||
|
} |
||||
|
|
||||
|
public copy(dest: vec4 | null = null): vec4 { |
||||
|
if (!dest) dest = new vec4(); |
||||
|
|
||||
|
dest.x = this.x; |
||||
|
dest.y = this.y; |
||||
|
dest.z = this.z; |
||||
|
dest.w = this.w; |
||||
|
|
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
public equals(vector: vec4, threshold = EPSILON): boolean { |
||||
|
if (Math.abs(this.x - vector.x) > threshold) |
||||
|
return false; |
||||
|
|
||||
|
if (Math.abs(this.y - vector.y) > threshold) |
||||
|
return false; |
||||
|
|
||||
|
if (Math.abs(this.z - vector.z) > threshold) |
||||
|
return false; |
||||
|
|
||||
|
if (Math.abs(this.w - vector.w) > threshold) |
||||
|
return false; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
static red: vec4 = new vec4([1.0, 0.0, 0.0, 1.0]); |
||||
|
static green: vec4 = new vec4([0.0, 1.0, 0.0, 1.0]); |
||||
|
static blue: vec4 = new vec4([0.0, 0.0, 1.0, 1.0]); |
||||
|
static black: vec4 = new vec4([0, 0, 0, 0]); |
||||
|
|
||||
|
static v0: vec4 = new vec4(); |
||||
|
static v1: vec4 = new vec4(); |
||||
|
static v2: vec4 = new vec4(); |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
export * from './Vec2'; |
||||
|
export * from './Vec3'; |
||||
|
export * from './Vec4'; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue