UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

549 lines • 17.3 kB
/** * Rotation representation in 3d space * @see https://en.wikipedia.org/wiki/Quaternion * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class Quaternion { /** * * @param {Vector3} axis * @param {number} angle * @returns {Quaternion} */ static fromAxisAngle(axis: Vector3, angle: number): Quaternion; /** * Create a randomly oriented quaternion * @param {function} [random] random number generator function * @returns {Quaternion} */ static random(random?: Function): Quaternion; /** * Convenience constructor * Used XYZ angle order (see {@link fromEulerAnglesXYZ}) * @param {number} x in radians * @param {number} y in radians * @param {number} z in radians * @returns {Quaternion} */ static fromEulerAngles(x: number, y: number, z: number): Quaternion; /** * Behaves similarly to Unity's Quaternion `RotateToward` method * @param {Quaternion} result * @param {Quaternion} from * @param {Quaternion} to * @param {number} max_delta in radians */ static rotateTowards(result: Quaternion, from: Quaternion, to: Quaternion, max_delta: number): void; /** * * @param {number} [x=0] * @param {number} [y=0] * @param {number} [z=0] * @param {number} [w=1] * @constructor */ constructor(x?: number, y?: number, z?: number, w?: number); /** * * @type {number} */ x: number; /** * * @type {number} */ y: number; /** * * @type {number} */ z: number; /** * * @type {number} */ w: number; /** * Fired when value of the quaternion changes * Signature of the signal data is as follows: * (new_x, new_y, new_z, new_w, old_x, old_y, old_z, old_w) * @readonly * @type {Signal<number, number, number, number, number, number, number, number>} */ readonly onChanged: Signal<number, number, number, number, number, number, number, number>; /** * * @param {number} v */ set 0(v: number); /** * * @return {number} */ get 0(): number; /** * * @param {number} v */ set 1(v: number); /** * * @return {number} */ get 1(): number; /** * * @param {number} v */ set 2(v: number); /** * * @return {number} */ get 2(): number; /** * * @param {number} v */ set 3(v: number); /** * * @return {number} */ get 3(): number; /** * Orient quaternion on a `forward` vector, with the spin matching `up` vector * Useful for `lookAt` operations, such as for camera or inverse kinematics * @param {number} fx forward vector * @param {number} fy forward vector * @param {number} fz forward vector * @param {number} ux up vector * @param {number} uy up vector * @param {number} uz up vector * @returns {this} */ _lookRotation(fx: number, fy: number, fz: number, ux: number, uy: number, uz: number): this; /** * * @param {Vector3} forward * @param {Vector3} [up=Vector3.up] */ lookRotation(forward: Vector3, up?: Vector3): void; /** * Vector dot product in 4 dimensions * @param {Quaternion} other * @return {number} */ dot(other: Quaternion): number; /** * Makes this quaternion into an inverse of the other * @param {Quaternion} other */ copyInverse(other: Quaternion): void; /** * Calculates the inverse * @returns {this} */ invert(): this; /** * Returns angle between this orientation and another * @param {Quaternion} other * @return {number} angle in radians */ angleTo(other: Quaternion): number; /** * * @param {Vector3} axis * @param {number} angle */ fromAxisAngle(axis: Vector3, angle: number): void; /** * * @param {number} ax * @param {number} ay * @param {number} az * @param {number} angle */ _fromAxisAngle(ax: number, ay: number, az: number, angle: number): void; /** * @see https://stackoverflow.com/questions/3684269/component-of-a-quaternion-rotation-around-an-axis * @param {Vector3} axis * @param {Quaternion} swing * @param {Quaternion} twist */ computeSwingAndTwist(axis: Vector3, swing: Quaternion, twist: Quaternion): void; /** * Compute rotation (twist) around input axis * @param {Vector3} axis * @returns {number} in radians */ computeTwistAngle(axis: Vector3): number; /** * * @param {Vector3} axis * @returns {number} angle in radians */ toAxisAngle(axis: Vector3): number; /** * * @returns {this} */ normalize(): this; /** * * @param {number} val * @return {this} */ multiplyScalar(val: number): this; /** * @param {Quaternion} other * @returns {this} */ multiply(other: Quaternion): this; /** * * @param {Quaternion} first * @param {Quaternion} second * @returns {this} */ multiplyQuaternions(first: Quaternion, second: Quaternion): this; /** * * @param {number} ax * @param {number} ay * @param {number} az * @param {number} aw * @param {number} bx * @param {number} by * @param {number} bz * @param {number} bw * @returns {this} */ _multiplyQuaternions(ax: number, ay: number, az: number, aw: number, bx: number, by: number, bz: number, bw: number): this; /** * * @return {number} */ length(): number; /** * * @param {Quaternion} other * @param {number} max_delta in radians * @returns {this} */ rotateTowards(other: Quaternion, max_delta: number): this; /** * * @param {Vector3} source * @param {Vector3} target * @param {Vector3} [up] */ lookAt(source: Vector3, target: Vector3, up?: Vector3): void; /** * @deprecated use {@link random} instead * @param {function():number} random */ setRandom(random: () => number): Quaternion; /** * * @param {number} x * @param {number} y * @param {number} z * @param {String} [order] a combination of capital letters X,Y,Z. Examples: XYZ, YXZ * @returns {Quaternion} */ __setFromEuler(x: number, y: number, z: number, order?: string): Quaternion; /** * @see https://localcoder.org/euler-angle-to-quaternion-then-quaternion-to-euler-angle * @see https://discourse.mcneel.com/t/what-is-the-right-method-to-convert-quaternion-to-plane-using-rhinocommon/92411/21?page=2 * @param {Vector3} result */ toEulerAnglesXYZ(result: Vector3): void; /** * Adapted from http://bediyap.com/programming/convert-quaternion-to-euler-rotations/ * @param {Vector3} result */ toEulerAnglesYXZ(result: Vector3): void; /** * Adapted from http://bediyap.com/programming/convert-quaternion-to-euler-rotations/ * @param {Vector3} result */ toEulerAnglesZYX(result: Vector3): void; /** * XYZ order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesXYZ(x: number, y: number, z: number): this; /** * YXZ order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesYXZ(x: number, y: number, z: number): this; /** * ZXY order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesZXY(x: number, y: number, z: number): this; /** * ZYX order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesZYX(x: number, y: number, z: number): this; /** * YZX order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesYZX(x: number, y: number, z: number): this; /** * XZY order * @source: https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine * @see http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m * @see https://github.com/mrdoob/three.js/blob/510705cde208b165fd87946b0f8504a1cd6dbe83/src/math/Quaternion.js#L206 * @param {number} x angle in X axis in radians * @param {number} y angle in Y axis in radians * @param {number} z angle in Z axis in radians * @returns {this} */ fromEulerAnglesXZY(x: number, y: number, z: number): this; /** * NOTE: Vectors need to be normalized * * @param {Vector3} from * @param {Vector3} to * @returns {this} */ fromUnitVectors(from: Vector3, to: Vector3): this; /** * @param {number[]} m4x4 * @returns {this} */ setFromRotationMatrix(m4x4: number[]): this; /** * This algorithm comes from "Quaternion Calculus and Fast Animation", * Ken Shoemake, 1987 SIGGRAPH course notes * @see https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Geometry/Quaternion.h#L813 * @param {number} m11 * @param {number} m12 * @param {number} m13 * @param {number} m21 * @param {number} m22 * @param {number} m23 * @param {number} m31 * @param {number} m32 * @param {number} m33 * @returns {this} */ __setFromRotationMatrix(m11: number, m12: number, m13: number, m21: number, m22: number, m23: number, m31: number, m32: number, m33: number): this; /** * Linear interpolation * @param {Quaternion} other * @param {number} t fractional value between 0 and 1 * @returns {this} */ lerp(other: Quaternion, t: number): this; /** * Linear interpolation of two quaternions * Pretty good, not as good as slerp, but close enough for most application * @param {Quaternion} first * @param {Quaternion} second * @param {number} t * @returns {this} */ lerpQuaternions(first: Quaternion, second: Quaternion, t: number): this; /** * Spherical linear interpolation * @param {Quaternion} from * @param {Quaternion} to * @param {number} t coefficient, how much between the input quats? * @returns {this} */ slerpQuaternions(from: Quaternion, to: Quaternion, t: number): this; /** * @see https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/quat.js * @param {Quaternion} other * @param {number} t * @returns {this} */ slerp(other: Quaternion, t: number): this; /** * * @param {function(x:number,y:number,z:number,w:number)} handler * @param {*} [thisArg] * @returns {this} */ process(handler: any, thisArg?: any): this; /** * * @param {Quaternion} other * @returns {this} */ copy(other: Quaternion): this; /** * * @returns {Quaternion} */ clone(): Quaternion; /** * Set current value of the quaternion * You *MUST* use this method in order for {@link Quaternion#onChanged} signal to be fired * @param {number} x * @param {number} y * @param {number} z * @param {number} w * @returns {this} */ set(x: number, y: number, z: number, w: number): this; /** * * @returns {this} */ conjugate(): this; toJSON(): { x: number; y: number; z: number; w: number; }; /** * * @param obj * @return {this} */ fromJSON(obj: any): this; /** * * @param {BinaryBuffer} buffer */ toBinaryBuffer(buffer: BinaryBuffer): void; /** * * @param {BinaryBuffer} buffer */ fromBinaryBuffer(buffer: BinaryBuffer): void; /** * * @param {BinaryBuffer} buffer */ toBinaryBufferFloat32(buffer: BinaryBuffer): void; /** * * @param {BinaryBuffer} buffer */ fromBinaryBufferFloat32(buffer: BinaryBuffer): void; /** * Based on GDC talk from Bungie on destiny, compressing quaternions for animation * @deprecated use `quat_decode_from_uint32` instead * @param {number} value */ decodeFromUint32(value: number): void; /** * Based on GDC talk from Bungie on destiny, compressing quaternions for animation * @deprecated use `quat_encode_to_uint32` instead * @returns {number} */ encodeToUint32(): number; /** * * @param {number[]} array * @param {number} [offset] * @returns {this} */ readFromArray(array: number[], offset?: number): this; /** * * @param {number[]} [array] * @param {number} [offset] * @returns {number[]} */ writeToArray(array?: number[], offset?: number): number[]; /** * * @param {Quaternion} other * @returns {boolean} */ equals(other: Quaternion): boolean; /** * * @returns {number} integer hash */ hash(): number; /** * Check for approximate equality between two quaternions * @param {Quaternion} other * @param {number} [tolerance] * @return {boolean} */ roughlyEquals(other: Quaternion, tolerance?: number): boolean; /** * * @param {number} x * @param {number} y * @param {number} z * @param {number} w * @param {number} [tolerance] * @return {boolean} */ _roughlyEquals(x: number, y: number, z: number, w: number, tolerance?: number): boolean; /** * Randomly orient current quaternion * @param {function():number} [random] Defaults to {@link Math.random} * @return {Quaternion} */ random(random?: () => number): Quaternion; toString(): string; fromArray: (array: number[], offset?: number) => Quaternion; toArray: (array?: number[], offset?: number) => number[]; asArray: (array?: number[], offset?: number) => number[]; fromEulerAngles: (x: number, y: number, z: number) => Quaternion; /** * Shortcut for type checking * @readonly * @type {boolean} */ readonly isQuaternion: boolean; /** * Making quaternion iterable * @returns {Generator<number>} */ [Symbol.iterator](): Generator<number>; } export namespace Quaternion { let identity: Quaternion; let typeName: string; } export default Quaternion; import Signal from "../events/signal/Signal.js"; import Vector3 from "./Vector3.js"; //# sourceMappingURL=Quaternion.d.ts.map