Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Added Matrix4.fromTranslationQuaternion #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/modules/core/api-reference/matrix4.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ Sets the matrix to a transformation corresponding to the rotations represented b

- `quaternion` (`Quaternion`) - the quaternion to create matrix from

##### fromTranslationQuaternion(translation: Vector3, quaternion: Quaternion): this

Sets the matrix to a transformation corresponding to the translation and rotations represented by the given parameters.

`matrix4.fromTranslationQuaternion(translation, quaternion)`

- `translation` (`Vector3`) - the translation to create matrix from
- `quaternion` (`Quaternion`) - the quaternion to create matrix from

##### `frustum(options: {left: number, right: number, bottom: number, top: number, near: number, far: number}): this`

Generates a frustum matrix with the given bounds. The frustum far plane can be infinite.
Expand Down
39 changes: 33 additions & 6 deletions modules/core/src/classes/matrix4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {vec2_transformMat4AsVector, vec3_transformMat4AsVector} from '../lib/gl-
// @ts-ignore gl-matrix types...
import {
fromQuat as mat4_fromQuat,
fromRotationTranslation as mat4_fromRotationTranslation,
frustum as mat4_frustum,
lookAt as mat4_lookAt,
ortho as mat4_ortho,
Expand Down Expand Up @@ -231,6 +232,20 @@ export class Matrix4 extends Matrix {
return this.check();
}

/**
* Calculates a 4x4 matrix from the given translation and quaternion
* @param translation Vector3 to create matrix from
* @param quaternion Quaternion to create matrix from
* @returns self
*/
fromTranslationQuaternion(
translation: Readonly<NumericArray>,
quaternion: Readonly<NumericArray>
): this {
mat4_fromRotationTranslation(this, quaternion, translation);
return this.check();
}

/**
* Generates a frustum matrix with the given bounds
* @param view.left - Left bound of the frustum
Expand Down Expand Up @@ -368,7 +383,9 @@ export class Matrix4 extends Matrix {
* @param result
* @returns self
*/
getScale(result: NumericArray = [-0, -0, -0]): NumericArray {
getScale(): NumericArray;
getScale<T extends NumericArray>(result: T): T;
getScale(result = [-0, -0, -0]): NumericArray {
// explicit is faster than hypot...
result[0] = Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]);
result[1] = Math.sqrt(this[4] * this[4] + this[5] * this[5] + this[6] * this[6]);
Expand All @@ -384,7 +401,9 @@ export class Matrix4 extends Matrix {
* @param result
* @returns self
*/
getTranslation(result: NumericArray = [-0, -0, -0]): NumericArray {
getTranslation(): NumericArray;
getTranslation<T extends NumericArray>(result: T): T;
getTranslation(result = [-0, -0, -0]): NumericArray {
result[0] = this[12];
result[1] = this[13];
result[2] = this[14];
Expand All @@ -397,8 +416,12 @@ export class Matrix4 extends Matrix {
* @param scaleResult
* @returns self
*/
getRotation(result?: NumericArray, scaleResult?: NumericArray): NumericArray {
result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0];
getRotation(scaleResult?: NumericArray): NumericArray;
getRotation<T extends NumericArray>(result: T, scaleResult?: NumericArray): T;
getRotation(
result = [-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0],
scaleResult?: NumericArray
): NumericArray {
scaleResult = scaleResult || [-0, -0, -0];
const scale = this.getScale(scaleResult);
const inverseScale0 = 1 / scale[0];
Expand Down Expand Up @@ -429,8 +452,12 @@ export class Matrix4 extends Matrix {
* @param scaleResult
* @returns self
*/
getRotationMatrix3(result?: NumericArray, scaleResult?: NumericArray): NumericArray {
result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0];
getRotationMatrix3(scaleResult?: NumericArray): NumericArray;
getRotationMatrix3<T extends NumericArray>(result: T, scaleResult?: NumericArray): T;
getRotationMatrix3(
result = [-0, -0, -0, -0, -0, -0, -0, -0, -0],
scaleResult?: NumericArray
): NumericArray {
scaleResult = scaleResult || [-0, -0, -0];
const scale = this.getScale(scaleResult);
const inverseScale0 = 1 / scale[0];
Expand Down
32 changes: 16 additions & 16 deletions modules/core/src/gl-matrix/quat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,22 +354,22 @@ export function slerp(out, a, b, t) {
* @param {quat} out the receiving quaternion
* @returns {quat} out
*/
// export function random(out) {
// // Implementation of http://planning.cs.uiuc.edu/node198.html
// // TODO: Calling random 3 times is probably not the fastest solution
// let u1 = glMatrix.RANDOM();
// let u2 = glMatrix.RANDOM();
// let u3 = glMatrix.RANDOM();

// let sqrt1MinusU1 = Math.sqrt(1 - u1);
// let sqrtU1 = Math.sqrt(u1);

// out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);
// out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);
// out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);
// out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);
// return out;
// }
export function random(out) {
// Implementation of http://planning.cs.uiuc.edu/node198.html
// TODO: Calling random 3 times is probably not the fastest solution
let u1 = glMatrix.RANDOM();
let u2 = glMatrix.RANDOM();
let u3 = glMatrix.RANDOM();

let sqrt1MinusU1 = Math.sqrt(1 - u1);
let sqrtU1 = Math.sqrt(u1);

out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);
out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);
out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);
out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);
return out;
}

/**
* Calculates the inverse of a quat
Expand Down
71 changes: 70 additions & 1 deletion modules/core/test/classes/matrix4.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// MIT License

/* eslint-disable max-statements */
import {Matrix4, Vector3, config, configure} from '@math.gl/core';
import {Matrix3, Matrix4, Quaternion, Vector3, config, configure} from '@math.gl/core';
import {random as vec3_random} from '../../src/gl-matrix/vec3';
import {random as quat_random} from '../../src/gl-matrix/quat';
import test from 'tape-promise/tape';
import {tapeEquals, tapeEqualsEpsilon} from 'test/utils/tape-assertions';

Expand Down Expand Up @@ -42,6 +44,20 @@ test('Matrix4#fromQuaternion', (t) => {
t.end();
});

test('Matrix4#fromTranslationQuaternion', (t) => {
const translation = new Vector3(vec3_random([-0, -0, -0], 100 * Math.random()));
const quaternion = new Quaternion(quat_random([-0, -0, -0, -0]));

tapeEquals(
t,
new Matrix4().fromTranslationQuaternion(translation, quaternion),
new Matrix4()
.fromQuaternion(quaternion)
.multiplyLeft(new Matrix4().identity().translate(translation))
);
t.end();
});

test('Matrix4#from', (t) => {
tapeEquals(t, new Matrix4().from(INDICES_MATRIX), INDICES_MATRIX);
// tapeEquals(t, new Matrix4().from({x: 1, y: 2, z: 3, w: 4}), [1, 2, 3, 4]);
Expand Down Expand Up @@ -159,6 +175,18 @@ test('Matrix4#getScale', (t) => {
t.end();
});

test('Matrix4#getScaleAsVector3', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = new Vector3([3.7416573867739413, 10.488088481701515, 17.37814719698276]);

const scale = new Matrix4(INPUT).getScale(new Vector3());

tapeEquals(t, scale instanceof Vector3, true);
tapeEquals(t, scale, RESULT, 'getScale gave the right result');

t.end();
});

test('Matrix4#getRotation', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = [
Expand All @@ -173,6 +201,21 @@ test('Matrix4#getRotation', (t) => {
t.end();
});

test('Matrix4#getRotationAsMatrix4', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = new Matrix4([
0.2672612419124244, 0.19069251784911848, 0.17263060129453078, 0, 1.3363062095621219,
0.5720775535473555, 0.4028047363539052, 0, 2.4053511772118195, 0.9534625892455924,
0.6329788714132796, 0, 0, 0, 0, 1
]);

const m = new Matrix4(INPUT).getRotation(new Matrix4(), [...INDICES_MATRIX]);
tapeEquals(t, m instanceof Matrix4, true);
tapeEquals(t, m, RESULT, 'getRotation gave the right result');

t.end();
});

test('Matrix4#getRotationMatrix3', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = [
Expand All @@ -187,6 +230,21 @@ test('Matrix4#getRotationMatrix3', (t) => {
t.end();
});

test('Matrix4#getRotationMatrix3AsMatrix3', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = new Matrix3([
0.2672612419124244, 0.19069251784911848, 0.17263060129453078, 1.3363062095621219,
0.5720775535473555, 0.4028047363539052, 2.4053511772118195, 0.9534625892455924,
0.6329788714132796
]);

const m = new Matrix4(INPUT).getRotationMatrix3(new Matrix3(), [...INDICES_MATRIX.slice(0, 9)]);
tapeEquals(t, m instanceof Matrix3, true);
tapeEquals(t, m, RESULT, 'getRotationMatrix3 gave the right result');

t.end();
});

test('Matrix4#getTranslation', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = [13, 14, 15];
Expand All @@ -197,6 +255,17 @@ test('Matrix4#getTranslation', (t) => {
t.end();
});

test('Matrix4#getTranslationAsVector3', (t) => {
const INPUT = INDICES_MATRIX;
const RESULT = new Vector3([13, 14, 15]);

const m = new Matrix4(INPUT).getTranslation(new Vector3());
tapeEquals(t, m instanceof Vector3, true);
tapeEquals(t, m, RESULT, 'getTranslation gave the right result');

t.end();
});

test('Matrix4#perspective#', (t) => {
const fovy = Math.PI * 0.5;
const result = new Matrix4().perspective({fovy, aspect: 1, near: 0, far: 1});
Expand Down
Loading