1/*******************************************************************************
2 * Copyright 2011 See AUTHORS file.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *   http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
16
17package com.badlogic.gdx.tests;
18
19import com.badlogic.gdx.Gdx;
20import com.badlogic.gdx.math.Matrix4;
21import com.badlogic.gdx.math.Vector3;
22import com.badlogic.gdx.tests.utils.GdxTest;
23import com.badlogic.gdx.utils.GdxRuntimeException;
24import com.badlogic.gdx.utils.TimeUtils;
25
26public class MatrixJNITest extends GdxTest {
27	@Override
28	public void create () {
29		Matrix4 mat1 = new Matrix4();
30		Matrix4 mat2 = new Matrix4();
31		Matrix4 mat3 = new Matrix4();
32		Vector3 vec = new Vector3(1, 2, 3);
33		float[] fvec = {1, 2, 3};
34		float[] fvecs = {1, 2, 3, 0, 0, 1, 2, 3, 0, 0, 1, 2, 3, 0, 0};
35
36		mat1.setToRotation(0, 1, 0, 45);
37		mat2.setToRotation(1, 0, 0, 45);
38
39		vec.mul(mat1);
40		Matrix4.mulVec(mat1.val, fvec);
41		Matrix4.mulVec(mat1.val, fvecs, 0, 3, 5);
42		check(vec, fvec);
43		check(vec, fvecs, 3, 5);
44
45		vec.prj(mat1);
46		Matrix4.prj(mat1.val, fvec);
47		Matrix4.prj(mat1.val, fvecs, 0, 3, 5);
48		check(vec, fvec);
49		check(vec, fvecs, 3, 5);
50
51		vec.rot(mat1);
52		Matrix4.rot(mat1.val, fvec);
53		Matrix4.rot(mat1.val, fvecs, 0, 3, 5);
54		check(vec, fvec);
55		check(vec, fvecs, 3, 5);
56
57		if (mat1.det() != Matrix4.det(mat1.val)) throw new GdxRuntimeException("det doesn't work");
58
59		mat2.set(mat1);
60		mat1.inv();
61		Matrix4.inv(mat2.val);
62		check(mat1, mat2);
63
64		mat3.set(mat1);
65		mat1.mul(mat2);
66		Matrix4.mul(mat3.val, mat2.val);
67		check(mat1, mat3);
68
69		bench();
70
71		System.out.println("All tests passed.");
72	}
73
74	private void bench () {
75		Matrix4 mata = new Matrix4();
76		Matrix4 matb = new Matrix4();
77
78		long start = TimeUtils.nanoTime();
79		for (int i = 0; i < 1000000; i++) {
80			mata.mul(matb);
81		}
82		Gdx.app.log("MatrixJNITest", "java matrix * matrix took: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
83
84		start = TimeUtils.nanoTime();
85		for (int i = 0; i < 1000000; i++) {
86			Matrix4.mul(mata.val, matb.val);
87		}
88		Gdx.app.log("MatrixJNITest", "jni matrix * matrix took: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
89
90		Vector3 vec = new Vector3();
91		start = TimeUtils.nanoTime();
92		for (int i = 0; i < 500000; i++) {
93			vec.mul(mata);
94		}
95		Gdx.app.log("MatrixJNITest", "java vecs * matrix took: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
96
97		float[] fvec = new float[3];
98		start = TimeUtils.nanoTime();
99		for (int i = 0; i < 500000; i++) {
100			Matrix4.mulVec(mata.val, fvec);
101		}
102		Gdx.app.log("MatrixJNITest", "jni vecs * matrix took: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
103
104		float[] fvecs = new float[3 * 500000];
105		start = TimeUtils.nanoTime();
106		Matrix4.mulVec(mata.val, fvecs, 0, 500000, 3);
107		Gdx.app.log("MatrixJNITest", "jni bulk vecs * matrix took: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
108
109		start = TimeUtils.nanoTime();
110		for (int i = 0; i < 1000000; i++) {
111			mata.inv();
112		}
113		Gdx.app.log("MatrixJNITest", "java inv(matrix): " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
114
115		start = TimeUtils.nanoTime();
116		for (int i = 0; i < 1000000; i++) {
117			Matrix4.inv(mata.val);
118		}
119		Gdx.app.log("MatrixJNITest", "jni inv(matrix): " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
120	}
121
122	private void check (Vector3 vec, float[] fvec) {
123		if (vec.x != fvec[0] || vec.y != fvec[1] || vec.z != fvec[2]) throw new GdxRuntimeException("vectors are not equal");
124	}
125
126	private void check (Vector3 vec, float[] fvec, int numVecs, int stride) {
127		int offset = 0;
128		for (int i = 0; i < numVecs; i++) {
129			if (vec.x != fvec[0] || vec.y != fvec[1] || vec.z != fvec[2]) throw new GdxRuntimeException("vectors are not equal");
130		}
131	}
132
133	private void check (Matrix4 mat1, Matrix4 mat2) {
134		for (int i = 0; i < 16; i++) {
135			if (mat1.val[i] != mat2.val[i]) throw new GdxRuntimeException("matrices not equal");
136		}
137	}
138}
139