From 86dad78a19143f79e38e7ed529d349e2f645d2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E6=96=8C=E5=8B=87?= Date: Sat, 24 Feb 2024 18:03:29 +0800 Subject: [PATCH 1/3] feat: add fromEuler method for a quaternion --- modules/core/src/classes/quaternion.ts | 46 ++++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/modules/core/src/classes/quaternion.ts b/modules/core/src/classes/quaternion.ts index d3b0b16d..515ec9c9 100644 --- a/modules/core/src/classes/quaternion.ts +++ b/modules/core/src/classes/quaternion.ts @@ -1,9 +1,9 @@ // Copyright (c) 2017 Uber Technologies, Inc. // MIT License -import {NumericArray} from '@math.gl/types'; -import {MathArray} from './base/math-array'; -import {checkNumber, checkVector} from '../lib/validators'; -import {Vector4} from './vector4'; +import { NumericArray } from '@math.gl/types'; +import { MathArray } from './base/math-array'; +import { checkNumber, checkVector } from '../lib/validators'; +import { Vector4 } from './vector4'; // @ts-ignore gl-matrix types... import { fromMat3 as quat_fromMat3, @@ -27,7 +27,8 @@ import { slerp as quat_slerp } from '../gl-matrix/quat'; // @ts-ignore gl-matrix types... -import {transformQuat as vec4_transformQuat} from '../gl-matrix/vec4'; +import { transformQuat as vec4_transformQuat } from '../gl-matrix/vec4'; +import { Euler } from './euler'; const IDENTITY_QUATERNION = [0, 0, 0, 1] as const; @@ -59,7 +60,7 @@ export class Quaternion extends MathArray { return this.check(); } - fromObject(object: {x: number; y: number; z: number; w: number}): this { + fromObject(object: { x: number; y: number; z: number; w: number }): this { this[0] = object.x; this[1] = object.y; this[2] = object.z; @@ -79,6 +80,31 @@ export class Quaternion extends MathArray { return this.check(); } + /** + * Creates a quaternion from the given Euler. + * @param m + * @returns + */ + fromEuler(euler: Euler): this { + this.identity(); + switch (euler.order) { + case Euler.XYZ: + return this.rotateX(this[0]).rotateY(this[1]).rotateZ(this[2]); + case Euler.YXZ: + return this.rotateY(this[0]).rotateX(this[1]).rotateZ(this[2]); + case Euler.ZXY: + return this.rotateZ(this[0]).rotateX(this[1]).rotateY(this[2]); + case Euler.ZYX: + return this.rotateZ(this[0]).rotateY(this[1]).rotateX(this[2]); + case Euler.YZX: + return this.rotateY(this[0]).rotateZ(this[1]).rotateX(this[2]); + case Euler.XZY: + return this.rotateX(this[0]).rotateZ(this[1]).rotateY(this[2]); + default: + throw new Error('Unknown Euler angle order'); + } + } + fromAxisRotation(axis: Readonly, rad: number): this { quat_setAxisAngle(this, axis, rad); return this.check(); @@ -280,10 +306,10 @@ export class Quaternion extends MathArray { arg0: | Readonly | { - start: Readonly; - target: Readonly; - ratio: number; - }, + start: Readonly; + target: Readonly; + ratio: number; + }, arg1?: Readonly | number, arg2?: number ): this { From ca609ecabbc54bbd9509856b35fb36c09225e57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E6=96=8C=E5=8B=87?= Date: Sat, 24 Feb 2024 18:39:04 +0800 Subject: [PATCH 2/3] feat: add fromMatrix3 method for a matrix4 --- modules/core/src/classes/matrix4.ts | 28 ++++++++++++++++++++++++++ modules/core/src/classes/quaternion.ts | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/modules/core/src/classes/matrix4.ts b/modules/core/src/classes/matrix4.ts index d05236aa..f256fff1 100644 --- a/modules/core/src/classes/matrix4.ts +++ b/modules/core/src/classes/matrix4.ts @@ -231,6 +231,34 @@ export class Matrix4 extends Matrix { return this.check(); } + /** + * Calculates a 4x4 matrix from the given matrix3 + * @param matrix3 + * @returns self + */ + fromMatrix3(matrix3: Readonly): this { + this[0] = matrix3[0]; + this[1] = matrix3[1]; + this[2] = matrix3[2]; + this[3] = 0; + + this[4] = matrix3[3]; + this[5] = matrix3[4]; + this[6] = matrix3[5]; + this[7] = 0; + + this[8] = matrix3[6]; + this[9] = matrix3[7]; + this[10] = matrix3[8]; + this[11] = 0; + + this[12] = 0; + this[13] = 0; + this[14] = 0; + this[15] = 1; + return this.check(); + } + /** * Generates a frustum matrix with the given bounds * @param view.left - Left bound of the frustum diff --git a/modules/core/src/classes/quaternion.ts b/modules/core/src/classes/quaternion.ts index 515ec9c9..7233364e 100644 --- a/modules/core/src/classes/quaternion.ts +++ b/modules/core/src/classes/quaternion.ts @@ -82,7 +82,7 @@ export class Quaternion extends MathArray { /** * Creates a quaternion from the given Euler. - * @param m + * @param euler * @returns */ fromEuler(euler: Euler): this { From 3570d0434e16d92cde1cfa5f47c6251a7f2faa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E6=96=8C=E5=8B=87?= Date: Sat, 24 Feb 2024 19:23:41 +0800 Subject: [PATCH 3/3] getQuaternion --- modules/core/src/classes/euler.ts | 18 +----------------- modules/core/src/classes/quaternion.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/modules/core/src/classes/euler.ts b/modules/core/src/classes/euler.ts index 4bd2aa93..c8cfa74a 100644 --- a/modules/core/src/classes/euler.ts +++ b/modules/core/src/classes/euler.ts @@ -285,23 +285,7 @@ export class Euler extends MathArray { // TODO - move to Quaternion getQuaternion(): Quaternion { - const q = new Quaternion(); - switch (this[3]) { - case RotationOrder.XYZ: - return q.rotateX(this[0]).rotateY(this[1]).rotateZ(this[2]); - case RotationOrder.YXZ: - return q.rotateY(this[0]).rotateX(this[1]).rotateZ(this[2]); - case RotationOrder.ZXY: - return q.rotateZ(this[0]).rotateX(this[1]).rotateY(this[2]); - case RotationOrder.ZYX: - return q.rotateZ(this[0]).rotateY(this[1]).rotateX(this[2]); - case RotationOrder.YZX: - return q.rotateY(this[0]).rotateZ(this[1]).rotateX(this[2]); - case RotationOrder.XZY: - return q.rotateX(this[0]).rotateZ(this[1]).rotateY(this[2]); - default: - throw new Error(ERR_UNKNOWN_ORDER); - } + return new Quaternion().fromEuler(this); } // INTERNAL METHODS diff --git a/modules/core/src/classes/quaternion.ts b/modules/core/src/classes/quaternion.ts index 7233364e..f506d233 100644 --- a/modules/core/src/classes/quaternion.ts +++ b/modules/core/src/classes/quaternion.ts @@ -89,17 +89,17 @@ export class Quaternion extends MathArray { this.identity(); switch (euler.order) { case Euler.XYZ: - return this.rotateX(this[0]).rotateY(this[1]).rotateZ(this[2]); + return this.rotateX(euler[0]).rotateY(euler[1]).rotateZ(euler[2]); case Euler.YXZ: - return this.rotateY(this[0]).rotateX(this[1]).rotateZ(this[2]); + return this.rotateY(euler[0]).rotateX(euler[1]).rotateZ(euler[2]); case Euler.ZXY: - return this.rotateZ(this[0]).rotateX(this[1]).rotateY(this[2]); + return this.rotateZ(euler[0]).rotateX(euler[1]).rotateY(euler[2]); case Euler.ZYX: - return this.rotateZ(this[0]).rotateY(this[1]).rotateX(this[2]); + return this.rotateZ(euler[0]).rotateY(euler[1]).rotateX(euler[2]); case Euler.YZX: - return this.rotateY(this[0]).rotateZ(this[1]).rotateX(this[2]); + return this.rotateY(euler[0]).rotateZ(euler[1]).rotateX(euler[2]); case Euler.XZY: - return this.rotateX(this[0]).rotateZ(this[1]).rotateY(this[2]); + return this.rotateX(euler[0]).rotateZ(euler[1]).rotateY(euler[2]); default: throw new Error('Unknown Euler angle order'); }