// Quaternion
export interface Quaternion {
x: number;
y: number;
z: number;
w: number;
}
/** @class
* @subcategory Math
* */
export class Quaternion {
x: number;
y: number;
z: number;
w: number;
constructor(x?: number, y?: number, z?: number, w?: number) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = w !== undefined ? w : 1;
}
set(x: number, y: number, z: number, w: number) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
}
copy(q: Quaternion) {
this.x = q.x;
this.y = q.y;
this.z = q.z;
this.w = q.w;
return this;
}
conjugate() {
this.x *= -1;
this.y *= -1;
this.z *= -1;
return this;
}
inverse() {
return this.conjugate().normalize();
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
lengthxyz() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
normalize() {
let l = this.length();
if (l === 0) {
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 1;
} else {
l = 1 / l;
this.x *= l;
this.y *= l;
this.z *= l;
this.w *= l;
}
return this;
}
multiply(q: any) {
return this.multiplyQuaternions(this, q);
}
multiplyScalar(s: number) {
this.x *= s;
this.y *= s;
this.z *= s;
this.w *= s;
return this;
}
multiplyQuaternions(a: Quaternion, b: Quaternion) {
const qax = a.x;
const qay = a.y;
const qaz = a.z;
const qaw = a.w;
const qbx = b.x;
const qby = b.y;
const qbz = b.z;
const qbw = b.w;
this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
return this;
}
sub(q: Quaternion) {
this.x -= q.x;
this.y -= q.y;
this.z -= q.z;
this.w -= q.w;
return this;
}
clone() {
return new Quaternion(this.x, this.y, this.z, this.w);
}
setFromEuler(e: Quaternion) {
const c1 = Math.cos(e.x / 2);
const c2 = Math.cos(e.y / 2);
const c3 = Math.cos(e.z / 2);
const s1 = Math.sin(e.x / 2);
const s2 = Math.sin(e.y / 2);
const s3 = Math.sin(e.z / 2);
this.x = s1 * c2 * c3 + c1 * s2 * s3;
this.y = c1 * s2 * c3 - s1 * c2 * s3;
this.z = c1 * c2 * s3 + s1 * s2 * c3;
this.w = c1 * c2 * c3 - s1 * s2 * s3;
return this;
}
}