Browse Source

矩阵转换开始

master
blobt 3 years ago
parent
commit
41cd51d590
  1. 396
      src/render/math/Mat4.ts
  2. 136
      src/render/math/Vec4.ts
  3. 3
      src/render/math/index.ts

396
src/render/math/Mat4.ts

@ -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;
}
}

136
src/render/math/Vec4.ts

@ -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();
}

3
src/render/math/index.ts

@ -0,0 +1,3 @@
export * from './Vec2';
export * from './Vec3';
export * from './Vec4';
Loading…
Cancel
Save