303 lines
6.4 KiB
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]);
|
|
}
|