1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 #include <gtest/gtest.h>
18 #include <math.h>
19 
20 #include "Matrix.h"
21 
22 class MatrixTest: public testing::Test {
23 public:
24 
25 };
26 
checkValues(const float * arr1,const float * arr2,const int size)27 void checkValues(const float* arr1, const float* arr2, const int size) {
28     for (int i = 0; i < size; i++) {
29         ASSERT_FLOAT_EQ(arr1[i], arr2[i]);
30     }
31 }
32 
TEST(MatrixTest,matrixEqualityTest)33 TEST(MatrixTest, matrixEqualityTest) {
34     // Create two identity matrixes.
35     Matrix m1;
36     Matrix m2;
37     // Change some random values.
38     m1.mData[4] = 9;
39     m2.mData[4] = 9;
40     // Check they are the same.
41     ASSERT_TRUE(m1.equals(m2));
42     Matrix* clone = new Matrix(m1);
43     ASSERT_TRUE(clone != NULL);
44     ASSERT_TRUE(m1.equals(*clone));
45     delete clone;
46 }
47 
TEST(MatrixTest,matrixIdentityTest)48 TEST(MatrixTest, matrixIdentityTest) {
49     // Create an identity matrix.
50     Matrix m;
51     float expected[] = {
52         1.0f, 0.0f, 0.0f, 0.0f,
53         0.0f, 1.0f, 0.0f, 0.0f,
54         0.0f, 0.0f, 1.0f, 0.0f,
55         0.0f, 0.0f, 0.0f, 1.0f};
56     // Check values
57     checkValues(m.mData, expected, Matrix::MATRIX_SIZE);
58 }
59 
TEST(MatrixTest,matrixLoadWithTest)60 TEST(MatrixTest, matrixLoadWithTest) {
61     // Create a matrix.
62     Matrix m1;
63     float* d1 = m1.mData;
64     float data[Matrix::MATRIX_SIZE];
65 
66     // Fill with rubbish
67     for (int i = 0; i < Matrix::MATRIX_SIZE; i++) {
68         d1[i] = i;
69         data[i] = i;
70     }
71 
72     // Create another matrix
73     Matrix m2;
74 
75     // Load second matrix with first
76     m2.loadWith(m1);
77 
78     // Check values
79     checkValues(m2.mData, data, Matrix::MATRIX_SIZE);
80 }
81 
TEST(MatrixTest,matrixTranslateTest)82 TEST(MatrixTest, matrixTranslateTest) {
83     Matrix m1;
84     m1.translate(10, 5, 6);
85     Matrix* m2 = Matrix::newTranslate(10, 5, 6);
86     ASSERT_TRUE(m2 != NULL);
87     ASSERT_TRUE(m1.equals(*m2));
88     delete m2;
89 }
90 
TEST(MatrixTest,matrixScaleTest)91 TEST(MatrixTest, matrixScaleTest) {
92     Matrix m1;
93     m1.scale(10, 5, 6);
94     Matrix* m2 = Matrix::newScale(10, 5, 6);
95     ASSERT_TRUE(m2 != NULL);
96     ASSERT_TRUE(m1.equals(*m2));
97     delete m2;
98 }
99 
TEST(MatrixTest,matrixRotateTest)100 TEST(MatrixTest, matrixRotateTest) {
101     Matrix m1;
102     m1.rotate(180, 1, 0, 1);
103     Matrix* m2 = Matrix::newRotate(180, 1, 0, 1);
104     ASSERT_TRUE(m2 != NULL);
105     ASSERT_TRUE(m1.equals(*m2));
106     delete m2;
107 }
108 
TEST(MatrixTest,matrixMultiplyTest)109 TEST(MatrixTest, matrixMultiplyTest) {
110     // Create three identity matrixes.
111     Matrix m1;
112     Matrix m2;
113     Matrix m3;
114     float* d1 = m1.mData;
115     float* d2 = m2.mData;
116 
117     m3.multiply(m1, m2);
118     // Multiplication of identity matrixes should give identity
119     ASSERT_TRUE(m3.equals(m1));
120 
121     // Fill with ascending numbers
122     for (int i = 0; i < Matrix::MATRIX_SIZE; i++) {
123         d1[i] = i;
124         d2[i] = i;
125     }
126     m3.multiply(m1, m2);
127 
128     // Check against expected
129     float expected[] = {
130         56, 62, 68, 74,
131         152, 174, 196, 218,
132         248, 286, 324, 362,
133         344, 398, 452, 506};
134     checkValues(m3.mData, expected, Matrix::MATRIX_SIZE);
135 }
136 
TEST(MatrixTest,matrixNewLookAtTest)137 TEST(MatrixTest, matrixNewLookAtTest) {
138     // Position the eye in front of the origin.
139     float eyeX = 0.0f;
140     float eyeY = 0.0f;
141     float eyeZ = 6.0f;
142 
143     // We are looking at the origin
144     float centerX = 0.0f;
145     float centerY = 0.0f;
146     float centerZ = 0.0f;
147 
148     // Set our up vector. This is where our head would be pointing were we holding the camera.
149     float upX = 0.0f;
150     float upY = 1.0f;
151     float upZ = 0.0f;
152 
153     // Set the view matrix. This matrix can be said to represent the camera position.
154     Matrix* m = Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ,
155             upX, upY, upZ);
156     ASSERT_TRUE(m != NULL);
157     float expected[] = {
158         1.0f, 0.0f, 0.0f, 0.0f,
159         0.0f, 1.0f, 0.0f, 0.0f,
160         0.0f, 0.0f, 1.0f, 0.0f,
161         0.0f, 0.0f, -6.0f, 1.0f};
162     // Check values
163     checkValues(m->mData, expected, Matrix::MATRIX_SIZE);
164     delete m;
165 }
166 
TEST(MatrixTest,matrixNewFrustumTest)167 TEST(MatrixTest, matrixNewFrustumTest) {
168     float ratio = (float) 800 / 600;
169     float left = -ratio;
170     float right = ratio;
171     float bottom = -1.0f;
172     float top = 1.0f;
173     float near = 1.0f;
174     float far = 8.0f;
175 
176     Matrix* m = Matrix::newFrustum(left, right, bottom, top, near, far);
177     ASSERT_TRUE(m != NULL);
178     float expected[] = {
179         0.75f, 0.0f, 0.0f, 0.0f,
180         0.0f, 1.0f, 0.0f, 0.0f,
181         0.0f, 0.0f, 9.0f / -7.0f, -1.0f,
182         0.0f, 0.0f, 16.0f / -7.0f, 0.0f};
183     // Check values
184     checkValues(m->mData, expected, Matrix::MATRIX_SIZE);
185     delete m;
186 }
187 
TEST(MatrixTest,matrixNewTranslateTest)188 TEST(MatrixTest, matrixNewTranslateTest) {
189     Matrix* m = Matrix::newTranslate(5, 6, 8);
190     ASSERT_TRUE(m != NULL);
191     float expected[] = {
192         1.0f, 0.0f, 0.0f, 0.0f,
193         0.0f, 1.0f, 0.0f, 0.0f,
194         0.0f, 0.0f, 1.0f, 0.0f,
195         5.0f, 6.0f, 8.0f, 1.0f};
196     // Check values
197     checkValues(m->mData, expected, Matrix::MATRIX_SIZE);
198     delete m;
199 }
200 
TEST(MatrixTest,matrixNewScaleTest)201 TEST(MatrixTest, matrixNewScaleTest) {
202     Matrix* m = Matrix::newScale(3, 7, 2);
203     ASSERT_TRUE(m != NULL);
204     float expected[] = {
205         3.0f, 0.0f, 0.0f, 0.0f,
206         0.0f, 7.0f, 0.0f, 0.0f,
207         0.0f, 0.0f, 2.0f, 0.0f,
208         0.0f, 0.0f, 0.0f, 1.0f};
209     // Check values
210     checkValues(m->mData, expected, Matrix::MATRIX_SIZE);
211     delete m;
212 }
213 
TEST(MatrixTest,matrixNewRotateTest)214 TEST(MatrixTest, matrixNewRotateTest) {
215     Matrix* m = Matrix::newRotate(45.0f, 0.0f, 1.0f, 0.0f);
216     ASSERT_TRUE(m != NULL);
217     float radians = 45.0f * (M_PI / 180.0f);
218     float sin = sinf(radians);
219     float cos = cosf(radians);
220     float expected[] = {
221         cos, 0.0f, -sin, 0.0f,
222         0.0f, 1.0f, 0.0f, 0.0f,
223         sin, 0.0f, cos, 0.0f,
224         0.0f, 0.0f, 0.0f, 1.0f};
225     // Check values
226     checkValues(m->mData, expected, Matrix::MATRIX_SIZE);
227     delete m;
228 }
229 
TEST(MatrixTest,matrixMultiplyVectorTest)230 TEST(MatrixTest, matrixMultiplyVectorTest) {
231     float in[] = {2, 4, 6, 8};
232     float out[4];
233     Matrix m;
234     float* d = m.mData;
235     // Fill with rubbish
236     for (int i = 0; i < Matrix::MATRIX_SIZE; i++) {
237         d[i] = i;
238     }
239     float expected[] = {40, 120, 200, 280};
240     Matrix::multiplyVector(out, m, in);
241     checkValues(out, expected, 4);
242 }
243