@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
591 lines • 19.4 kB
TypeScript
/**
* Implementation of a quaternion.
* Represents rotation in 3d space
*
* Iterating through a Quaternion instance will yield its components `(x, y, z, w)` in the corresponding order.
* Note that a quaternion must be {@link normalize}d to properly represent rotation. Check documentation of individual operations when in doubt.
* @see https://en.wikipedia.org/wiki/Quaternion
* @implements Iterable<number>
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
export class Quaternion implements Iterable<number> {
/**
*
* @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;
/**
* Fires when the 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(arg: number);
/**
*
* @return {number}
*/
get 0(): number;
/**
*
* @param {number} v
*/
set 1(arg: number);
/**
*
* @return {number}
*/
get 1(): number;
/**
*
* @param {number} v
*/
set 2(arg: number);
/**
*
* @return {number}
*/
get 2(): number;
/**
*
* @param {number} v
*/
set 3(arg: 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.
* Normalizes input, meaning input does not have to be normalized.
*
* NOTE: `forward` and `up` vectors being the same is allowed, but you will likely get unexpected rotation along the look axis, so prefer not to do it.
*
* @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;
/**
* Orient quaternion to align with the `forward` direction.
* @param {Vector3} forward Does not need to be normalized.
* @param {Vector3} [up=Vector3.up] Does not need to be normalized.
* @returns {this}
*/
lookRotation(forward: Vector3, up?: Vector3): this;
/**
* 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
* @returns {this}
*/
copyInverse(other: Quaternion): this;
/**
* Calculates the inverse.
* Correctly handles unnormalized quaternions.
*
* If your quaternion is normalized, you can use {@link conjugate} instead for speed.
* @returns {this}
* @see conjugate
*/
invert(): this;
/**
* NOTE: this is the same as {@link invert} if the quaternion is normalized.
* @returns {this}
* @see invert
*/
conjugate(): this;
/**
* Returns angle between this orientation and another
* @param {Quaternion} other
* @return {number} angle in radians
*/
angleTo(other: Quaternion): number;
/**
* Set quaternion from axis + angle definition
* @param {Vector3} axis
* @param {number} angle
* @returns {this}
*/
fromAxisAngle(axis: Vector3, angle: number): this;
/**
*
* @param {number} axis_x
* @param {number} axis_y
* @param {number} axis_z
* @param {number} angle
* @returns {this}
*/
_fromAxisAngle(axis_x: number, axis_y: number, axis_z: number, angle: number): this;
/**
* Given a direction axis, compute rotation quaternions from current rotation to that axis as swing and twist. Swing moves to a given orientation while without "twisting",
* `twist` just the twist around the given axis, no change in orientation.
* @param {Vector3} axis
* @param {Quaternion} swing Swing quaternion will be written here
* @param {Quaternion} twist Twist quaternion will be written here
* @returns {void}
* @see slerp
*/
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;
/**
* Decompose quaternion to the axis of rotation and angle around this axis.
* @param {Vector3} out_axis axis will be written here
* @returns {number} angle in radians
*/
toAxisAngle(out_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]
* @see lookRotation
*/
lookAt(source: Vector3, target: Vector3, up?: Vector3): void;
/**
* @deprecated use {@link fromEulerAnglesXYZ} or others specifically.
*
* @param {number} x
* @param {number} y
* @param {number} z
* @param {String} [order='XYZ'] a combination of capital letters X,Y,Z. Examples: XYZ, YXZ
* @returns {this}
*
* @see fromEulerAnglesXYZ
* @see fromEulerAnglesYXZ
* @see fromEulerAnglesZXY
* @see fromEulerAnglesZYX
* @see fromEulerAnglesYZX
* @see fromEulerAnglesXZY
*/
__setFromEuler(x: number, y: number, z: number, order?: string): this;
/**
* @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;
/**
* Set rotation from Euler angles in degrees.
*
* Order is explicitly XYZ.
*
* Utility shortcut, same as `fromEulerAnglesXYZ(x * π / 180, y * π / 180, z * π / 180)`
*
* @param {number} [x] angle in degrees
* @param {number} [y] angle in degrees
* @param {number} [z] angle in degrees
* @returns {this}
*
* @see fromEulerAnglesXYZ
*/
fromDegrees(x?: number, y?: number, z?: number): this;
/**
* 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 Must be normalized
* @param {Vector3} to Must be normalized
* @returns {this}
*/
fromUnitVectors(from: Vector3, to: Vector3): this;
/**
* @param {number[]|Float32Array} m4x4
* @returns {this}
*/
setFromRotationMatrix(m4x4: number[] | Float32Array): 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 quaternions? Must be a value between 0 and 1
* @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;
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;
/**
*
* @param {number[]} array
* @param {number} [offset]
* @returns {this}
*/
fromArray(array: number[], offset?: number): this;
/**
*
* @param {number[]} [array]
* @param {number} [offset]
* @returns {number[]}
*/
toArray(array?: number[], offset?: number): number[];
/**
* Strict equality check
* @param {Quaternion} other
* @returns {boolean}
* @see roughlyEquals
*/
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] acceptable difference value per coordinate
* @return {boolean}
*/
_roughlyEquals(x: number, y: number, z: number, w: number, tolerance?: number): boolean;
/**
* @deprecated use {@link random} instead
* @param {function():number} random
*/
setRandom(random: () => number): void;
/**
* Randomly orient current quaternion
* @param {function():number} [random=Math.random] Random number generator function.
*/
random(random?: () => number): this;
toString(): string;
/**
* @deprecated use `fromArray`
*/
readFromArray: (array: number[], offset?: number) => this;
/**
* @deprecated use `toArray`
*/
writeToArray: (array?: number[], offset?: number) => number[];
/**
* @deprecated use `toArray`
*/
asArray: (array?: number[], offset?: number) => number[];
fromEulerAngles: (x: number, y: number, z: number) => this;
/**
* 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