diff --git a/src/mat3-impl.ts b/src/mat3-impl.ts index 0d5f77d..abf0e07 100644 --- a/src/mat3-impl.ts +++ b/src/mat3-impl.ts @@ -792,7 +792,7 @@ const rotateZ = rotate; /** * Creates a 3-by-3 matrix which scales in each dimension by an amount given by - * the corresponding entry in the given vector; assumes the vector has three + * the corresponding entry in the given vector; assumes the vector has two * entries. * @param v - A vector of * 2 entries specifying the factor by which to scale in each dimension. @@ -812,7 +812,7 @@ function scaling(v: Vec2Arg, dst?: T) { /** * Scales the given 3-by-3 matrix in each dimension by an amount * given by the corresponding entry in the given vector; assumes the vector has - * three entries. + * two entries. * @param m - The matrix to be modified. * @param v - A vector of 2 entries specifying the * factor by which to scale in each dimension. @@ -843,7 +843,58 @@ function scale(m: Mat3Arg, v: Vec2Arg, dst?: T) { } /** - * Creates a 3-by-3 matrix which scales uniformly in each dimension + * Creates a 3-by-3 matrix which scales in each dimension by an amount given by + * the corresponding entry in the given vector; assumes the vector has three + * entries. + * @param v - A vector of + * 3 entries specifying the factor by which to scale in each dimension. + * @param dst - matrix to hold result. If not passed a new one is created. + * @returns The scaling matrix. + */ +function scaling3D(v: Vec3Arg, dst?: T) { + const newDst = (dst ?? new Ctor(12)) as T; + + newDst[ 0] = v[0]; newDst[ 1] = 0; newDst[ 2] = 0; + newDst[ 4] = 0; newDst[ 5] = v[1]; newDst[ 6] = 0; + newDst[ 8] = 0; newDst[ 9] = 0; newDst[10] = v[2]; + + return newDst; +} + +/** + * Scales the given 3-by-3 matrix in each dimension by an amount + * given by the corresponding entry in the given vector; assumes the vector has + * three entries. + * @param m - The matrix to be modified. + * @param v - A vector of 3 entries specifying the + * factor by which to scale in each dimension. + * @param dst - matrix to hold result. If not passed a new one is created. + * @returns The scaled matrix. + */ +function scale3D(m: Mat3Arg, v: Vec3Arg, dst?: T) { + const newDst = (dst ?? new Ctor(12)) as T; + + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + + newDst[ 0] = v0 * m[0 * 4 + 0]; + newDst[ 1] = v0 * m[0 * 4 + 1]; + newDst[ 2] = v0 * m[0 * 4 + 2]; + + newDst[ 4] = v1 * m[1 * 4 + 0]; + newDst[ 5] = v1 * m[1 * 4 + 1]; + newDst[ 6] = v1 * m[1 * 4 + 2]; + + newDst[ 8] = v2 * m[2 * 4 + 0]; + newDst[ 9] = v2 * m[2 * 4 + 1]; + newDst[10] = v2 * m[2 * 4 + 2]; + + return newDst; +} + +/** + * Creates a 3-by-3 matrix which scales uniformly in the X and Y dimensions * @param s - Amount to scale * @param dst - matrix to hold result. If not passed a new one is created. * @returns The scaling matrix. @@ -859,7 +910,7 @@ function uniformScaling(s: number, dst?: T) { } /** - * Scales the given 3-by-3 matrix in each dimension by an amount + * Scales the given 3-by-3 matrix in the X and Y dimension by an amount * given. * @param m - The matrix to be modified. * @param s - Amount to scale. @@ -886,6 +937,48 @@ function uniformScale(m: Mat3Arg, s: number, dst?: return newDst; } +/** + * Creates a 3-by-3 matrix which scales uniformly in each dimension + * @param s - Amount to scale + * @param dst - matrix to hold result. If not passed a new one is created. + * @returns The scaling matrix. + */ +function uniformScaling3D(s: number, dst?: T) { + const newDst = (dst ?? new Ctor(12)) as T; + + newDst[ 0] = s; newDst[ 1] = 0; newDst[ 2] = 0; + newDst[ 4] = 0; newDst[ 5] = s; newDst[ 6] = 0; + newDst[ 8] = 0; newDst[ 9] = 0; newDst[10] = s; + + return newDst; +} + +/** + * Scales the given 3-by-3 matrix in each dimension by an amount + * given. + * @param m - The matrix to be modified. + * @param s - Amount to scale. + * @param dst - matrix to hold result. If not passed a new one is created. + * @returns The scaled matrix. + */ +function uniformScale3D(m: Mat3Arg, s: number, dst?: T) { + const newDst = (dst ?? new Ctor(12)) as T; + + newDst[ 0] = s * m[0 * 4 + 0]; + newDst[ 1] = s * m[0 * 4 + 1]; + newDst[ 2] = s * m[0 * 4 + 2]; + + newDst[ 4] = s * m[1 * 4 + 0]; + newDst[ 5] = s * m[1 * 4 + 1]; + newDst[ 6] = s * m[1 * 4 + 2]; + + newDst[ 8] = s * m[2 * 4 + 0]; + newDst[ 9] = s * m[2 * 4 + 1]; + newDst[10] = s * m[2 * 4 + 2]; + + return newDst; +} + return { clone, create, @@ -923,6 +1016,10 @@ return { scale, uniformScaling, uniformScale, + scaling3D, + scale3D, + uniformScaling3D, + uniformScale3D, }; } diff --git a/test/tests/mat3-test.js b/test/tests/mat3-test.js index ea93dc4..30691d2 100644 --- a/test/tests/mat3-test.js +++ b/test/tests/mat3-test.js @@ -542,6 +542,28 @@ function check(mat3, Type) { }, expected); }); + it('should make 3D scaling matrix', () => { + const expected = [ + 2, 0, 0, 0, + 0, 3, 0, 0, + 0, 0, 4, 0, + ]; + testMat3WithAndWithoutDest((newDst) => { + return mat3.scaling3D([2, 3, 4], newDst); + }, expected); + }); + + it('should scale 3D', () => { + const expected = [ + 0, 2, 4, 0, + 12, 15, 18, 0, + 32, 36, 40, 0, + ]; + testMat3WithAndWithoutDest((newDst) => { + return mat3.scale3D(m, [2, 3, 4], newDst); + }, expected); + }); + it('should make uniform scaling matrix', () => { const expected = [ 2, 0, 0, 0, @@ -564,6 +586,28 @@ function check(mat3, Type) { }, expected); }); + it('should make uniform scaling 3D matrix', () => { + const expected = [ + 2, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 2, 0, + ]; + testMat3WithAndWithoutDest((newDst) => { + return mat3.uniformScaling3D(2, newDst); + }, expected); + }); + + it('should uniformly scale 3D', () => { + const expected = [ + 0, 2, 4, 0, + 8, 10, 12, 0, + 16, 18, 20, 0, + ]; + testMat3WithAndWithoutDest((newDst) => { + return mat3.uniformScale3D(m, 2, newDst); + }, expected); + }); + it('should make a mat3 from mat4', () => { const expected = [ 1, 2, 3, 0,