1 /*
2 * This file is part of the Colobot: Gold Edition source code
3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see http://gnu.org/licenses
18 */
19
20 /* Unit tests for functions in geometry.h */
21
22 #include "math/func.h"
23 #include "math/geometry.h"
24
25 #include <gtest/gtest.h>
26
27
28 const float TEST_TOLERANCE = 1e-5;
29
30
31 // Test for rewritten function RotateAngle()
TEST(GeometryTest,RotateAngleTest)32 TEST(GeometryTest, RotateAngleTest)
33 {
34 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, 0.0f), 0.0f, TEST_TOLERANCE));
35
36 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, 0.0f), 0.0f, TEST_TOLERANCE));
37
38 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, 1.0f), 0.25f * Math::PI, TEST_TOLERANCE));
39
40 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, 2.0f), 0.5f * Math::PI, TEST_TOLERANCE));
41
42 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-0.5f, 0.5f), 0.75f * Math::PI, TEST_TOLERANCE));
43
44 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-1.0f, 0.0f), Math::PI, TEST_TOLERANCE));
45
46 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-1.0f, -1.0f), 1.25f * Math::PI, TEST_TOLERANCE));
47
48 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, -2.0f), 1.5f * Math::PI, TEST_TOLERANCE));
49
50 EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, -1.0f), 1.75f * Math::PI, TEST_TOLERANCE));
51 }
52
53 // Tests for other altered, complex or uncertain functions
54
55 /*
56
57 TODO: write meaningful tests with proper test values
58
59 int TestAngle()
60 {
61 const Math::Vector u(-0.0786076246943884, 0.2231249091714256, -1.1601361718477805);
62 const Math::Vector v(-1.231228742001907, -1.720549809950561, -0.690468438834111);
63
64 float mathResult = Math::Angle(u, v);
65 float oldMathResult = Angle(VEC_TO_D3DVEC(u), VEC_TO_D3DVEC(v));
66
67 if (! Math::IsEqual(mathResult, oldMathResult, TEST_TOLERANCE) )
68 return __LINE__;
69
70 return 0;
71 }
72
73 int TestRotateView()
74 {
75 const Math::Vector center(0.617909142705555, 0.896939729454538, -0.615041943652284);
76 const float angleH = 44.5;
77 const float angleV = 12.3;
78 const float dist = 34.76;
79
80 Math::Vector mathResult = Math::RotateView(center, angleH, angleV, dist);
81 Math::Vector oldMathResult = D3DVEC_TO_VEC(RotateView(VEC_TO_D3DVEC(center), angleH, angleV, dist));
82
83 if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
84 return __LINE__;
85
86 return 0;
87 }
88
89 int TestLookatPoint()
90 {
91 const Math::Vector eye(-2.451183170579471, 0.241270270546559, -0.490677411454893);
92 const float angleH = 48.4;
93 const float angleV = 32.4;
94 const float length = 74.44;
95
96 Math::Vector mathResult = Math::LookatPoint(eye, angleH, angleV, length);
97 Math::Vector oldMathResult = D3DVEC_TO_VEC(LookatPoint(VEC_TO_D3DVEC(eye), angleH, angleV, length));
98
99 if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
100 return __LINE__;
101
102 return 0;
103 }
104
105 int TestProjection()
106 {
107 const Math::Vector a(0.852064846846319, -0.794279497087496, -0.655779805476688);
108 const Math::Vector b(-0.245838834102304, -0.841115596038861, 0.470457161487799);
109 const Math::Vector p(2.289326061164255, -0.505511362271196, 0.660204551169491);
110
111 Math::Vector mathResult = Math::Projection(a, b, p);
112 Math::Vector oldMathResult = D3DVEC_TO_VEC(Projection(VEC_TO_D3DVEC(a), VEC_TO_D3DVEC(b), VEC_TO_D3DVEC(p)));
113
114 if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
115 return __LINE__;
116
117 return 0;
118 }
119
120 int TestLoadViewMatrix()
121 {
122 const Math::Vector from(2.5646013154868874, -0.6058794133917031, -0.0441195127419744);
123 const Math::Vector at(0.728044925765569, -0.206343977871841, 2.543158236935463);
124 const Math::Vector worldUp(-1.893738133660711, -1.009584441407070, 0.521745988225582);
125
126 Math::Matrix mathResult;
127 Math::LoadViewMatrix(mathResult, from, at, worldUp);
128
129 Math::Matrix oldMathResult;
130 {
131 D3DMATRIX mat;
132 D3DVECTOR fromD3D = VEC_TO_D3DVEC(from);
133 D3DVECTOR atD3D = VEC_TO_D3DVEC(at);
134 D3DVECTOR worldUpD3D = VEC_TO_D3DVEC(worldUp);
135 D3DUtil_SetViewMatrix(mat, fromD3D, atD3D, worldUpD3D);
136 oldMathResult = D3DMAT_TO_MAT(mat);
137 }
138
139 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
140 return __LINE__;
141
142 return 0;
143 }
144
145 int TestLoadProjectionMatrix()
146 {
147 const float fov = 76.3f;
148 const float aspect = 0.891f;
149 const float nearPlane = 12.3f;
150 const float farPlane = 1238.9f;
151
152 Math::Matrix mathResult;
153 Math::LoadProjectionMatrix(mathResult, fov, aspect, nearPlane, farPlane);
154
155 Math::Matrix oldMathResult;
156 {
157 D3DMATRIX mat;
158 D3DUtil_SetProjectionMatrix(mat, fov, aspect, nearPlane, farPlane);
159 oldMathResult = D3DMAT_TO_MAT(mat);
160 }
161
162 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
163 return __LINE__;
164
165 return 0;
166 }
167
168 int TestLoadTranslationMatrix()
169 {
170 const Math::Vector translation(-0.3631590720995237, 1.6976327614875211, 0.0148815191502145);
171
172 Math::Matrix mathResult;
173 Math::LoadTranslationMatrix(mathResult, translation);
174
175 Math::Matrix oldMathResult;
176 {
177 D3DMATRIX mat;
178 D3DUtil_SetTranslateMatrix(mat, translation.x, translation.y, translation.z);
179 oldMathResult = D3DMAT_TO_MAT(mat);
180 }
181
182 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
183 return __LINE__;
184
185 return 0;
186 }
187
188 int TestLoadScaleMatrix()
189 {
190 const Math::Vector scale(0.612236460285503, -0.635566935025364, -0.254321375332065);
191
192 Math::Matrix mathResult;
193 Math::LoadScaleMatrix(mathResult, scale);
194
195 Math::Matrix oldMathResult;
196 {
197 D3DMATRIX mat;
198 D3DUtil_SetScaleMatrix(mat, scale.x, scale.y, scale.z);
199 oldMathResult = D3DMAT_TO_MAT(mat);
200 }
201
202 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
203 return __LINE__;
204
205 return 0;
206 }
207
208 int TestLoadRotationXMatrix()
209 {
210 const float angle = 0.513790685774275;
211
212 Math::Matrix mathResult;
213 Math::LoadRotationXMatrix(mathResult, angle);
214
215 Math::Matrix oldMathResult;
216 {
217 D3DMATRIX mat;
218 D3DUtil_SetRotateXMatrix(mat, angle);
219 oldMathResult = D3DMAT_TO_MAT(mat);
220 }
221
222 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
223 return __LINE__;
224
225 return 0;
226 }
227
228 int TestLoadRotationYMatrix()
229 {
230 const float angle = -0.569166650127303;
231
232 Math::Matrix mathResult;
233 Math::LoadRotationYMatrix(mathResult, angle);
234
235 Math::Matrix oldMathResult;
236 {
237 D3DMATRIX mat;
238 D3DUtil_SetRotateYMatrix(mat, angle);
239 oldMathResult = D3DMAT_TO_MAT(mat);
240 }
241
242 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
243 return __LINE__;
244
245 return 0;
246 }
247
248 int TestLoadRotationZMatrix()
249 {
250 const float angle = 0.380448034347452;
251
252 Math::Matrix mathResult;
253 Math::LoadRotationZMatrix(mathResult, angle);
254
255 Math::Matrix oldMathResult;
256 {
257 D3DMATRIX mat;
258 D3DUtil_SetRotateZMatrix(mat, angle);
259 oldMathResult = D3DMAT_TO_MAT(mat);
260 }
261
262 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
263 return __LINE__;
264
265 return 0;
266 }
267
268 int TestLoadRotationMatrix()
269 {
270 const float angle = -0.987747190637790;
271 const Math::Vector dir(-0.113024727688331, -0.781265998072571, 1.838972397076884);
272
273 Math::Matrix mathResult;
274 Math::LoadRotationMatrix(mathResult, dir, angle);
275
276 Math::Matrix oldMathResult;
277 {
278 D3DMATRIX mat;
279 D3DVECTOR dirD3D = VEC_TO_D3DVEC(dir);
280 D3DUtil_SetRotationMatrix(mat, dirD3D, angle);
281 oldMathResult = D3DMAT_TO_MAT(mat);
282 }
283
284 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
285 return __LINE__;
286
287 return 0;
288 }
289
290 int TestLoadRotationXZYMatrix()
291 {
292 const Math::Vector angles(-0.841366567984597, -0.100543315396357, 1.610647811559988);
293
294 Math::Matrix mathResult;
295 Math::LoadRotationXZYMatrix(mathResult, angles);
296
297 Math::Matrix oldMathResult;
298 {
299 D3DMATRIX mat;
300 MatRotateXZY(mat, VEC_TO_D3DVEC(angles));
301 oldMathResult = D3DMAT_TO_MAT(mat);
302 }
303
304 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
305 return __LINE__;
306
307 return 0;
308 }
309
310 int TestLoadRotationZXYMatrix()
311 {
312 const Math::Vector angles(0.275558495480206, -0.224328265970090, 0.943077216574253);
313
314 Math::Matrix mathResult;
315 Math::LoadRotationZXYMatrix(mathResult, angles);
316
317 Math::Matrix oldMathResult;
318 {
319 D3DMATRIX mat;
320 MatRotateZXY(mat, VEC_TO_D3DVEC(angles));
321 oldMathResult = D3DMAT_TO_MAT(mat);
322 }
323
324 if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
325 return __LINE__;
326
327 return 0;
328 }
329
330 int TestTransform()
331 {
332 Math::Matrix transformMatrix(
333 (float[4][4])
334 {
335 { -0.9282074720977896, 0.6794734970319730, -1.3234304946882685, 0.0925294727863890 },
336 { -0.0395527963683484, 0.2897634352353881, 1.9144398570315440, -1.4062267508968478 },
337 { 0.9133323625282361, -0.6741836434774530, -0.2188812951424338, -1.0089184339952666 },
338 { 0.0f, 0.0f, 0.0f, 1.0f }
339 }
340 );
341 Math::Vector vector(-0.314596433318370, -0.622681232583150, -0.371307535743574);
342
343 Math::Vector mathResult = Math::Transform(transformMatrix, vector);
344 Math::Vector oldMathResult = Transform(transformMatrix, vector);
345
346 if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
347 return __LINE__;
348
349 return 0;
350 }
351
352 */
353
354