Decompose transform matrix in native (for android).

Summary:
This diff translates implementation of transform matrix decomposition from JS to java. This is to support offloading animations of transform property, in which case it is required that we can calculate decomposed transform in the UI thread.

Since the matrix decomposition code is not being used for other platform I went ahead and deleted parts that are no longer being used.

**Test plan**
Run UIExplorer Transform example before and after - compare the results
Closes https://github.com/facebook/react-native/pull/7916

Reviewed By: ritzau

Differential Revision: D3398393

Pulled By: astreet

fbshipit-source-id: 9881c3f565e2050e415849b0f76a0cefe11c6afb
This commit is contained in:
Krzysztof Magiera
2016-06-21 11:24:31 -07:00
committed by Facebook Github Bot 8
parent d1690a8f9e
commit a59afb98d5
5 changed files with 534 additions and 43 deletions

View File

@@ -0,0 +1,156 @@
package com.facebook.react.uimanager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import static org.fest.assertions.api.Assertions.assertThat;
/**
* Test for {@link MatrixMathHelper}
*/
@RunWith(RobolectricTestRunner.class)
public class MatrixMathHelperTest {
private void verifyZRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) {
MatrixMathHelper.MatrixDecompositionContext ctx =
new MatrixMathHelper.MatrixDecompositionContext();
double[] matrix = createRotateZ(degreesToRadians(degrees));
MatrixMathHelper.decomposeMatrix(matrix, ctx);
assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ);
}
private void verifyYRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) {
MatrixMathHelper.MatrixDecompositionContext ctx =
new MatrixMathHelper.MatrixDecompositionContext();
double[] matrix = createRotateY(degreesToRadians(degrees));
MatrixMathHelper.decomposeMatrix(matrix, ctx);
assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ);
}
private void verifyXRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) {
MatrixMathHelper.MatrixDecompositionContext ctx =
new MatrixMathHelper.MatrixDecompositionContext();
double[] matrix = createRotateX(degreesToRadians(degrees));
MatrixMathHelper.decomposeMatrix(matrix, ctx);
assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ);
}
@Test
public void testDecomposing4x4MatrixToProduceAccurateZaxisAngles() {
MatrixMathHelper.MatrixDecompositionContext ctx =
new MatrixMathHelper.MatrixDecompositionContext();
MatrixMathHelper.decomposeMatrix(
new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},
ctx);
assertThat(ctx.rotationDegrees).containsSequence(0d, 0d, 0d);
double[] angles = new double[]{30, 45, 60, 75, 90, 100, 115, 120, 133, 167};
for (double angle : angles) {
verifyZRotatedMatrix(angle, 0d, 0d, angle);
verifyZRotatedMatrix(-angle, 0d, 0d, -angle);
}
verifyZRotatedMatrix(180d, 0d, 0d, 180d);
// all values are between 0 and 180;
// change of sign and direction in the third and fourth quadrant
verifyZRotatedMatrix(222, 0d, 0d, -138d);
verifyZRotatedMatrix(270, 0d, 0d, -90d);
// 360 is expressed as 0
verifyZRotatedMatrix(360, 0d, 0d, 0d);
verifyZRotatedMatrix(33.33333333, 0d, 0d, 33.333d);
verifyZRotatedMatrix(86.75309, 0d, 0d, 86.753d);
verifyZRotatedMatrix(42.00000000001, 0d, 0d, 42d);
verifyZRotatedMatrix(42.99999999999, 0d, 0d, 43d);
verifyZRotatedMatrix(42.99999999999, 0d, 0d, 43d);
verifyZRotatedMatrix(42.49999999999, 0d, 0d, 42.5d);
verifyZRotatedMatrix(42.55555555555, 0d, 0d, 42.556d);
}
@Test
public void testDecomposing4x4MatrixToProduceAccurateYaxisAngles() {
double[] angles = new double[]{30, 45, 60, 75, 90, 100, 110, 120, 133, 167};
for (double angle : angles) {
verifyYRotatedMatrix(angle, 0d, angle, 0d);
verifyYRotatedMatrix(-angle, 0d, -angle, 0d);
}
// all values are between 0 and 180;
// change of sign and direction in the third and fourth quadrant
verifyYRotatedMatrix(222, 0d, -138d, 0d);
verifyYRotatedMatrix(270, 0d, -90d, 0d);
verifyYRotatedMatrix(360, 0d, 0d, 0d);
}
@Test
public void testDecomposing4x4MatrixToProduceAccurateXaxisAngles() {
double[] angles = new double[]{30, 45, 60, 75, 90, 100, 110, 120, 133, 167};
for (double angle : angles) {
verifyXRotatedMatrix(angle, angle, 0d, 0d);
verifyXRotatedMatrix(-angle, -angle, 0d, 0d);
}
// all values are between 0 and 180;
// change of sign and direction in the third and fourth quadrant
verifyXRotatedMatrix(222, -138d, 0d, 0d);
verifyXRotatedMatrix(270, -90d, 0d, 0d);
verifyXRotatedMatrix(360, 0d, 0d, 0d);
}
private static double[] createIdentityMatrix() {
return new double[] {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
}
private static double degreesToRadians(double degrees) {
return degrees * Math.PI / 180;
}
private static double[] createRotateZ(double radians) {
double[] mat = createIdentityMatrix();
mat[0] = Math.cos(radians);
mat[1] = Math.sin(radians);
mat[4] = -Math.sin(radians);
mat[5] = Math.cos(radians);
return mat;
}
private static double[] createRotateY(double radians) {
double[] mat = createIdentityMatrix();
mat[0] = Math.cos(radians);
mat[2] = -Math.sin(radians);
mat[8] = Math.sin(radians);
mat[10] = Math.cos(radians);
return mat;
}
private static double[] createRotateX(double radians) {
double[] mat = createIdentityMatrix();
mat[5] = Math.cos(radians);
mat[6] = Math.sin(radians);
mat[9] = -Math.sin(radians);
mat[10] = Math.cos(radians);
return mat;
}
}