web 3d图形渲染器
 
 
 

303 lines
6.4 KiB

import { EPSILON } from "../common";
export class vec3 {
/**
* @var
*/
public values = new Float32Array(3);
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 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 constructor(values: number[] | null = null) {
if (values !== null) {
this.x = values[0];
this.y = values[1];
this.z = values[2];
} else {
this.x = this.y = this.z = 0;
}
}
public at(index: number): number {
return this.values[index];
}
public reset(x: number = 0, y: number = 0, z: number = 0): void {
this.x = x;
this.y = y;
this.z = z;
}
public copy(dest: vec3 | null = null): vec3 {
if (!dest) dest = new vec3();
dest.x = this.x;
dest.y = this.y;
dest.z = this.z;
return dest;
}
/**
* 取负向量
* @param dest
* @returns
*/
public negate(dest: vec3 | null = null): vec3 {
if (!dest) dest = this;
dest.x = -this.x;
dest.y = -this.y;
dest.z = -this.z;
return dest;
}
/**
* 判断是否相等
* @param vector
* @param threshold
* @returns
*/
public equals(vector: vec3, 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;
return true;
}
/**
* 获取向量的模
*/
public get length(): number {
return Math.sqrt(this.length2);
}
/**
* 向量模的平方
*/
public get length2(): number {
let x = this.x,
y = this.y,
z = this.z;
return (x * x + y * y + z * z);
}
/**
* 向量相加
* @param vector
* @returns
*/
add(vector: vec3): vec3 {
this.x += vector.x;
this.y += vector.y;
this.z += vector.z;
return this;
}
/**
* 向量相减
* @param vector
* @returns
*/
subtract(vector: vec3): vec3 {
this.x -= vector.x;
this.y -= vector.y;
this.z -= vector.z;
return this;
}
/**
* 向量缩放
* @param value
* @param dest
* @returns
*/
public scale(value: number, dest: vec3 | null = null): vec3 {
if (!dest) {
dest = this;
} else {
this.copy(dest);
}
dest.x *= value;
dest.y *= value;
dest.z *= value;
return dest;
}
/**
* 向量单位化
* @param dest
* @returns
*/
public normalize(dest: vec3 | null = null): vec3 {
if (!dest) {
dest = this;
}
let length = this.length;
if (length === 1) {
return this;
}
if (length === 0) {
dest.x = 0
dest.y = 0;
dest.z = 0;
return dest;
}
dest.x /= length;
dest.y /= length;
dest.z /= length;
return dest;
}
/**
* 向量单位化
* @returns
*/
public normalize2(): number {
let length = this.length;
this.x /= length;
this.y /= length;
this.z /= length;
return length;
}
public print(): void {
console.log("[ " +
this.x + " " +
this.y + " " +
this.z
+" ]");
}
/**
* 向量缩放
* @param vector
* @param value
* @param dest
* @returns
*/
public static multiplyScalar(vector: vec3, value: number, dest: vec3 | null = null): vec3 {
if (!dest) dest = new vec3();
dest.x *= value;
dest.y *= value;
dest.z *= value;
return dest;
}
/**
* 向量叉乘
* @param vector
* @param vector2
* @param dest
* @returns
*/
public static cross(vector: vec3, vector2: vec3, dest: vec3 | null = null): vec3 {
if (!dest) dest = new vec3();
let x = vector.x,
y = vector.y,
z = vector.z;
let x2 = vector2.x,
y2 = vector2.y,
z2 = vector2.z;
dest.x = y * z2 - z * y2;
dest.y = z * x2 - x * z2;
dest.z = x * y2 - y * x2;
return dest;
}
/**
* 向量点乘
* @param vector
* @param vector2
* @returns
*/
public static dot(vector: vec3, vector2: vec3): number {
let x = vector.x,
y = vector.y,
z = vector.z;
let x2 = vector2.x,
y2 = vector2.y,
z2 = vector2.z;
return (x * x2 + y * y2 + z * z2);
}
public static sum(vector: vec3, vector2: vec3, dest: vec3 | null = null): vec3 {
if (!dest) dest = new vec3();
dest.x = vector.x + vector2.x;
dest.y = vector.y + vector2.y;
dest.z = vector.z + vector2.z;
return dest;
}
public static difference(vector: vec3, vector2: vec3, dest: vec3 | null = null): vec3 {
if (!dest) dest = new vec3();
dest.x = vector.x - vector2.x;
dest.y = vector.y - vector2.y;
dest.z = vector.z - vector2.z;
return dest;
}
static readonly up = new vec3([0, 1, 0]);
static readonly down = new vec3([0, -1, 0]);
static readonly right = new vec3([1, 0, 0]);
static readonly left = new vec3([-1, 0, 0]);
static readonly forward = new vec3([0, 0, 1]);
static readonly backward = new vec3([0, 0, -1]);
static readonly zero = new vec3([0, 0, 0]);
static v0 = new vec3([0, 0, 0]);
static v1 = new vec3([0, 0, 0]);
static v2 = new vec3([0, 0, 0]);
}