diff --git a/src/mat3-impl.ts b/src/mat3-impl.ts index 4b1db03..40c935e 100644 --- a/src/mat3-impl.ts +++ b/src/mat3-impl.ts @@ -25,7 +25,9 @@ import { QuatArg } from './quat'; import { Mat3Arg, Mat3Type } from './mat3'; import { Mat4Arg } from './mat4'; import { Vec2Arg } from './vec2'; +import { Vec3Arg } from './vec3'; import { getAPI as getVec2API } from './vec2-impl'; +import { getAPI as getVec3API } from './vec3-impl'; import { BaseArgType } from './types'; export { Mat3Arg, Mat3Type }; @@ -37,6 +39,7 @@ type Mat3Ctor = new (n: number) => T; * */ function getAPIImpl(Ctor: Mat3Ctor) { const vec2 = getVec2API(Ctor); + const vec3 = getVec3API(Ctor); /** * Create a Mat3 from values @@ -502,11 +505,11 @@ function setAxis(m: Mat3Arg, v: Vec2Arg, axis: numb return newDst; } -///** -// * Returns the scaling component of the matrix -// * @param m - The Matrix -// * @param dst - The vector to set. If not passed a new one is created. -// */ +/** + * Returns the "2d" scaling component of the matrix + * @param m - The Matrix + * @param dst - The vector to set. If not passed a new one is created. + */ function getScaling(m: Mat3Arg, dst?: T) { const newDst = (dst ?? vec2.create()); @@ -521,6 +524,32 @@ function getScaling(m: Mat3Arg, dst?: T) { return newDst; } + +/** + * Returns the "3d" scaling component of the matrix + * @param m - The Matrix + * @param dst - The vector to set. If not passed a new one is created. + */ +function get3DScaling(m: Mat3Arg, dst?: T) { + const newDst = (dst ?? vec3.create()); + + const xx = m[0]; + const xy = m[1]; + const xz = m[2]; + const yx = m[4]; + const yy = m[5]; + const yz = m[6]; + const zx = m[8]; + const zy = m[9]; + const zz = m[10]; + + newDst[0] = Math.sqrt(xx * xx + xy * xy + xz * xz); + newDst[1] = Math.sqrt(yx * yx + yy * yy + yz * yz); + newDst[2] = Math.sqrt(zx * zx + zy * zy + zz * zz); + + return newDst; +} + /** * Creates a 3-by-3 matrix which translates by the given vector v. * @param v - The vector by which to translate. @@ -750,6 +779,7 @@ return { getAxis, setAxis, getScaling, + get3DScaling, translation, translate, rotation, diff --git a/test/tests/mat3-test.js b/test/tests/mat3-test.js index a93df57..3ccde0c 100644 --- a/test/tests/mat3-test.js +++ b/test/tests/mat3-test.js @@ -70,6 +70,24 @@ function check(mat3, Type) { testV2WithDest(func, expected); } + function testV3WithoutDest(func, expected) { + const d = func(); + assertEqual(d, expected); + } + + function testV3WithDest(func, expected) { + const d = new Type(3).fill(0); + const c = func(d); + assertStrictEqual(c, d); + assertEqual(c, expected); + } + + function testVec3WithAndWithoutDest(func, expected) { + expected = createCopyOfType(expected); + testV3WithoutDest(func, expected); + testV3WithDest(func, expected); + } + it('should create', () => { const tests = [ {e: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], args: []}, @@ -365,6 +383,23 @@ function check(mat3, Type) { }, expected); }); + it('should get 3D scaling', () => { + const m = [ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + ]; + const expected = [ + Math.sqrt(1 * 1 + 2 * 2 + 3 * 3), + Math.sqrt(5 * 5 + 6 * 6 + 7 * 7), + Math.sqrt(9 * 9 + 10 * 10 + 11 * 11), + ]; + testVec3WithAndWithoutDest((newDst) => { + return mat3.get3DScaling(m, newDst); + }, expected); + }); + it('should make translation matrix', () => { const expected = [ 1, 0, 0, 0,