2020-04-03 19:11:42 +00:00
|
|
|
describe('CanvasKit\'s Matrix Helpers', () => {
|
2020-02-21 22:15:22 +00:00
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
beforeEach(async () => {
|
|
|
|
await LoadCanvasKit;
|
|
|
|
});
|
|
|
|
|
2020-07-06 23:50:13 +00:00
|
|
|
const expectArrayCloseTo = (a, b, precision) => {
|
|
|
|
precision = precision || 14 // digits of precision in base 10
|
2020-02-21 22:15:22 +00:00
|
|
|
expect(a.length).toEqual(b.length);
|
|
|
|
for (let i=0; i<a.length; i++) {
|
2020-07-06 23:50:13 +00:00
|
|
|
expect(a[i]).toBeCloseTo(b[i], precision);
|
2020-02-21 22:15:22 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
describe('3x3 matrices', () => {
|
2020-02-21 22:15:22 +00:00
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a translated 3x3 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.translated(5, -1),
|
2020-04-03 19:11:42 +00:00
|
|
|
[1, 0, 5,
|
|
|
|
0, 1, -1,
|
|
|
|
0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a scaled 3x3 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.scaled(2, 3),
|
2020-04-03 19:11:42 +00:00
|
|
|
[2, 0, 0,
|
|
|
|
0, 3, 0,
|
|
|
|
0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a rotated 3x3 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.rotated(Math.PI, 9, 9),
|
2020-04-03 19:11:42 +00:00
|
|
|
[-1, 0, 18,
|
|
|
|
0, -1, 18,
|
|
|
|
0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a skewed 3x3 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.skewed(4, 3, 2, 1),
|
2020-04-03 19:11:42 +00:00
|
|
|
[1, 4, -8,
|
|
|
|
3, 1, -3,
|
|
|
|
0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can multiply 3x3 matrices', () => {
|
|
|
|
const a = [
|
|
|
|
0.1, 0.2, 0.3,
|
|
|
|
0.0, 0.6, 0.7,
|
|
|
|
0.9, -0.9, -0.8,
|
|
|
|
];
|
|
|
|
const b = [
|
|
|
|
2.0, 3.0, 4.0,
|
|
|
|
-3.0, -4.0, -5.0,
|
|
|
|
7.0, 8.0, 9.0,
|
|
|
|
];
|
|
|
|
const expected = [
|
|
|
|
1.7, 1.9, 2.1,
|
|
|
|
3.1, 3.2, 3.3,
|
|
|
|
-1.1, -0.1, 0.9,
|
|
|
|
];
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.multiply(a, b),
|
2020-04-03 19:11:42 +00:00
|
|
|
expected);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('satisfies the inverse rule for 3x3 matrics', () => {
|
2020-02-21 22:15:22 +00:00
|
|
|
// a matrix times its inverse is the identity matrix.
|
2020-04-03 19:11:42 +00:00
|
|
|
const a = [
|
|
|
|
0.1, 0.2, 0.3,
|
|
|
|
0.0, 0.6, 0.7,
|
|
|
|
0.9, -0.9, -0.8,
|
|
|
|
];
|
2020-10-07 20:09:22 +00:00
|
|
|
const b = CanvasKit.Matrix.invert(a);
|
2020-04-03 19:11:42 +00:00
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.multiply(a, b),
|
|
|
|
CanvasKit.Matrix.identity());
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('maps 2D points correctly with a 3x3 matrix', () => {
|
2020-02-21 22:15:22 +00:00
|
|
|
const a = [
|
|
|
|
3, 0, -4,
|
|
|
|
0, 2, 4,
|
|
|
|
0, 0, 1,
|
|
|
|
];
|
|
|
|
const points = [
|
|
|
|
0, 0,
|
|
|
|
1, 1,
|
|
|
|
];
|
|
|
|
const expected = [
|
|
|
|
-4, 4,
|
|
|
|
-1, 6,
|
|
|
|
];
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.Matrix.mapPoints(a, points),
|
2020-02-21 22:15:22 +00:00
|
|
|
expected);
|
|
|
|
});
|
|
|
|
|
|
|
|
}); // describe 3x3
|
2020-04-03 19:11:42 +00:00
|
|
|
describe('4x4 matrices', () => {
|
|
|
|
|
|
|
|
it('can make a translated 4x4 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.translated([5, 6, 7]),
|
2020-04-03 19:11:42 +00:00
|
|
|
[1, 0, 0, 5,
|
|
|
|
0, 1, 0, 6,
|
|
|
|
0, 0, 1, 7,
|
|
|
|
0, 0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a scaled 4x4 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.scaled([5, 6, 7]),
|
2020-04-03 19:11:42 +00:00
|
|
|
[5, 0, 0, 0,
|
|
|
|
0, 6, 0, 0,
|
|
|
|
0, 0, 7, 0,
|
|
|
|
0, 0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a rotated 4x4 matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.rotated([1,1,1], Math.PI),
|
2020-04-03 19:11:42 +00:00
|
|
|
[-1/3, 2/3, 2/3, 0,
|
|
|
|
2/3, -1/3, 2/3, 0,
|
|
|
|
2/3, 2/3, -1/3, 0,
|
|
|
|
0, 0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a 4x4 matrix looking from eye to center', () => {
|
|
|
|
eye = [1, 0, 0];
|
|
|
|
center = [1, 0, 1];
|
|
|
|
up = [0, 1, 0]
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.lookat(eye, center, up),
|
2020-04-03 19:11:42 +00:00
|
|
|
[-1, 0, 0, 1,
|
|
|
|
0, 1, 0, 0,
|
|
|
|
0, 0, -1, 0,
|
|
|
|
0, 0, 0, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can make a 4x4 prespective matrix', () => {
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.perspective(2, 10, Math.PI/2),
|
2020-04-03 19:11:42 +00:00
|
|
|
[1, 0, 0, 0,
|
|
|
|
0, 1, 0, 0,
|
|
|
|
0, 0, 1.5, 5,
|
|
|
|
0, 0, -1, 1]);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('can multiply 4x4 matrices', () => {
|
|
|
|
const a = [
|
|
|
|
0.1, 0.2, 0.3, 0.4,
|
|
|
|
0.0, 0.6, 0.7, 0.8,
|
|
|
|
0.9, -0.9, -0.8, -0.7,
|
|
|
|
-0.6, -0.5, -0.4, -0.3,
|
|
|
|
];
|
|
|
|
const b = [
|
|
|
|
2.0, 3.0, 4.0, 5.0,
|
|
|
|
-3.0, -4.0, -5.0, -6.0,
|
|
|
|
7.0, 8.0, 9.0, 10.0,
|
|
|
|
-4.0, -3.0, -2.0, -1.0,
|
|
|
|
];
|
|
|
|
const expected = [
|
|
|
|
0.1, 0.7, 1.3, 1.9,
|
|
|
|
-0.1, 0.8, 1.7, 2.6,
|
|
|
|
1.7, 2.0, 2.3, 2.6,
|
|
|
|
-1.3, -2.1, -2.9, -3.7,
|
|
|
|
];
|
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.multiply(a, b),
|
2020-04-03 19:11:42 +00:00
|
|
|
expected);
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
|
|
|
|
2020-04-03 19:11:42 +00:00
|
|
|
it('satisfies the identity rule for 4x4 matrices', () => {
|
|
|
|
const a = [
|
|
|
|
0.1, 0.2, 0.3, 0.4,
|
|
|
|
0.0, 0.6, 0.7, 0.8,
|
|
|
|
0.9, 0.9, -0.8, -0.7,
|
|
|
|
-0.6, -0.5, -0.4, -0.3,
|
|
|
|
];
|
2020-10-07 20:09:22 +00:00
|
|
|
const b = CanvasKit.M44.invert(a)
|
2020-04-03 19:11:42 +00:00
|
|
|
expectArrayCloseTo(
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit.M44.multiply(a, b),
|
|
|
|
CanvasKit.M44.identity());
|
2020-02-21 22:15:22 +00:00
|
|
|
});
|
2020-07-06 23:50:13 +00:00
|
|
|
|
|
|
|
it('can create a camera setup matrix', () => {
|
|
|
|
const camAngle = Math.PI / 12;
|
|
|
|
const cam = {
|
|
|
|
'eye' : [0, 0, 1 / Math.tan(camAngle/2) - 1],
|
|
|
|
'coa' : [0, 0, 0],
|
|
|
|
'up' : [0, 1, 0],
|
|
|
|
'near' : 0.02,
|
|
|
|
'far' : 4,
|
|
|
|
'angle': camAngle,
|
|
|
|
};
|
2020-10-07 20:09:22 +00:00
|
|
|
const mat = CanvasKit.M44.setupCamera(CanvasKit.LTRBRect(0, 0, 200, 200), 200, cam);
|
2020-07-06 23:50:13 +00:00
|
|
|
// these values came from an invocation of setupCamera visually inspected.
|
|
|
|
const expected = [
|
|
|
|
7.595754, 0, -0.5, 0,
|
|
|
|
0, 7.595754, -0.5, 0,
|
|
|
|
0, 0, 1.010050, -1324.368418,
|
|
|
|
0, 0, -0.005, 7.595754];
|
|
|
|
expectArrayCloseTo(mat, expected, 5);
|
|
|
|
});
|
2020-02-21 22:15:22 +00:00
|
|
|
}); // describe 4x4
|
2020-10-07 20:09:22 +00:00
|
|
|
});
|