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'; |
Reference in new issue
xxxxxxxxxx