UNPKG

@osbjs/osbjs

Version:

a minimalist osu! storyboarding framework

230 lines (229 loc) 7.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Vector3 = void 0; const _1 = require("."); class Vector3 { constructor(x = 0, y = 0, z = 0) { this.x = x; this.y = y; this.z = z; } /** * Returns true if the components of this vector and v are strictly equal; false otherwise. */ equals(v) { return this.x === v.x && this.y === v.y && this.z === v.z; } /** * Returns a new Vector3 with the same x, y, z values as this one. */ clone() { return new Vector3(this.x, this.y, this.z); } /** * Computes the Euclidean distance between the two given points. */ distanceTo(v) { return Math.sqrt(this.distanceToSqr(v)); } /** * Computes the Euclidean distance squared between the two given points. */ distanceToSqr(v) { const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; } /** * Returns the length of the vector. */ length() { return Math.sqrt(this.lengthSqr()); } /** * Returns the length of the vector squared. */ lengthSqr() { return this.x * this.x + this.y * this.y + this.z * this.z; } /** * Returns the angle between this vector and vector v in radians. */ angleTo(v) { const denominator = Math.sqrt(this.lengthSqr() * v.lengthSqr()); if (denominator === 0) return Math.PI / 2; const theta = Vector3.dot(this, v) / denominator; // clamp, to handle numerical problems return Math.acos((0, _1.clamp)(theta, -1, 1)); } /** * Adds two vectors together. */ static add(v1, v2) { return new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); } /** * Subtracts the second vector from the first. */ static sub(v1, v2) { return new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); } /** * Returns a new vector whose values are the product of each pair of elements in two specified vectors. */ static multiply(v1, v2) { return new Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); } /** * Divides the first vector by the second. */ static divide(v1, v2) { return new Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); } /** * Adds the scalar value s to this vector's x, y values. */ static addScalar(v, s) { return new Vector3(v.x + s, v.y + s, v.z + s); } /** * Subtracts the scalar value s to this vector's x, y values. */ static subScalar(v, s) { return new Vector3(v.x - s, v.y - s, v.z - s); } /** * Multiplies a vector by a specified scalar. */ static multiplyScalar(v, s) { return new Vector3(v.x * s, v.y * s, v.z * s); } /** * Divides the specified vector by a specified scalar value. */ static divideScalar(v, s) { return Vector3.multiplyScalar(v, 1 / s); } /** * Transforms a vector by the specified Quaternion rotation value. */ static applyQuat(v, q) { const x = v.x, y = v.y, z = v.z, qx = q.x, qy = q.y, qz = q.z, qw = q.w; let result = new Vector3(); // calculate quat * vector const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat result.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; result.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; result.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; return result; } /** * Transforms a vector by a specified 4x4 matrix. */ static applyMat4(v, m) { // prettier-ignore return new Vector3(v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41, v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42, v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43); } /** * Transforms a vector by a specified 3x3 matrix. */ static applyMat3(v, m) { // prettier-ignore return new Vector3(v.x * m.m11 + v.y * m.m21 + v.z * m.m31, v.x * m.m12 + v.y * m.m22 + v.z * m.m32, v.x * m.m13 + v.y * m.m23 + v.z * m.m33); } /** * Linearly interpolate between v1 and v2, * where alpha is the percent distance along the line - alpha = 0 will be this vector, * and alpha = 1 will be v. */ static lerp(v1, v2, alpha) { let result = new Vector3(); result.x = v1.x + (v2.x - v1.x) * alpha; result.y = v1.y + (v2.y - v1.y) * alpha; result.z = v1.z + (v2.z - v1.z) * alpha; return result; } /** * Returns a vector whose elements are the maximum of each of the pairs of elements in two specified vectors. */ static max(v1, v2) { let result = new Vector3(); result.x = Math.max(v1.x, v2.x); result.y = Math.max(v1.y, v2.y); result.z = Math.max(v1.z, v2.z); return result; } /** * Returns a vector whose elements are the minimum of each of the pairs of elements in two specified vectors. */ static min(v1, v2) { let result = new Vector3(); result.x = Math.min(v1.x, v2.x); result.y = Math.min(v1.y, v2.y); result.z = Math.min(v1.z, v2.z); return result; } /** * Returns the dot product of two vectors. */ static dot(v1, v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } /** * Returns the cross product of two vectors. */ static cross(v1, v2) { let result = new Vector3(); result.x = v1.y * v2.z - v1.z * v2.y; result.y = v1.z * v2.x - v1.x * v2.z; result.z = v1.x * v2.y - v1.y * v2.x; return result; } /** * Negates a specified vector. */ static negate(v) { return Vector3.multiplyScalar(v, -1); } /** * Returns a vector with the same direction as the specified vector, but with a length of one. */ static normalize(v) { return Vector3.divideScalar(v, v.length() || 1); } /** * Returns a vector whose elements are the absolute values of each of the specified vector's elements. */ static abs(v) { return new Vector3(Math.abs(v.x), Math.abs(v.y), Math.abs(v.z)); } /** * Returns the reflection of a vector off a surface that has the specified normal. */ static reflect(v, normal) { // reflect incident vector off plane orthogonal to normal // normal is assumed to have unit length return Vector3.sub(v, Vector3.multiplyScalar(normal, 2 * Vector3.dot(v, normal))); } /** * Restricts a vector between a minimum and a maximum value. */ static clamp(v, min, max) { let result = new Vector3(); // assumes min < max, componentwise result.x = Math.max(min.x, Math.min(max.x, v.x)); result.y = Math.max(min.y, Math.min(max.y, v.y)); result.z = Math.max(min.z, Math.min(max.z, v.z)); return result; } } exports.Vector3 = Vector3; Vector3.One = new Vector3(1, 1, 1); Vector3.UnitX = new Vector3(1, 0, 0); Vector3.UnitY = new Vector3(0, 1, 0); Vector3.UnitZ = new Vector3(0, 0, 1); Vector3.Zero = new Vector3();