]> git.localhorst.tv Git - blobs.git/blob - tst/world/OrbitTest.cpp
add ray/box intersect test
[blobs.git] / tst / world / OrbitTest.cpp
1 #include "OrbitTest.hpp"
2
3 #include "../assert.hpp"
4
5 #include "math/const.hpp"
6 #include "world/Orbit.hpp"
7
8 CPPUNIT_TEST_SUITE_REGISTRATION(blobs::world::test::OrbitTest);
9
10 using blobs::test::AssertEqual;
11
12
13 namespace blobs {
14 namespace world {
15 namespace test {
16
17 void OrbitTest::setUp() {
18 }
19
20 void OrbitTest::tearDown() {
21 }
22
23
24 void OrbitTest::testDefault() {
25         Orbit orbit;
26         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
27                 "wrong semi-major axis on default orbit",
28                 1.0, orbit.SemiMajorAxis(), std::numeric_limits<double>::epsilon()
29         );
30         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
31                 "wrong eccentricity on default orbit",
32                 0.0, orbit.Eccentricity(), std::numeric_limits<double>::epsilon()
33         );
34         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
35                 "wrong inclination on default orbit",
36                 0.0, orbit.Inclination(), std::numeric_limits<double>::epsilon()
37         );
38         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
39                 "wrong longitude of ascending node on default orbit",
40                 0.0, orbit.LongitudeAscending(), std::numeric_limits<double>::epsilon()
41         );
42         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
43                 "wrong argument of periapsis on default orbit",
44                 0.0, orbit.ArgumentPeriapsis(), std::numeric_limits<double>::epsilon()
45         );
46         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
47                 "wrong mean anomaly on default orbit",
48                 0.0, orbit.MeanAnomaly(), std::numeric_limits<double>::epsilon()
49         );
50
51         // reference direction is +X, so at t=0, the body should be
52         // at (sma,0,0) relative to its parent
53         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
54         AssertEqual(
55                 "wrong position at t=0",
56                 glm::vec3(1.0f, 0.0f, 0.0f),
57                 glm::vec3(pos) / pos.w
58         );
59
60         // at 90° position should be (0,0,sma) since the zero inclination
61         // reference plane is XZ and rotates counter-clockwise
62         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
63         AssertEqual(
64                 "wrong position at t=90°",
65                 glm::vec3(0.0f, 0.0f, -1.0f),
66                 glm::vec3(pos) / pos.w
67         );
68
69         // at 180° position should be (-sma,0,0)
70         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
71         AssertEqual(
72                 "wrong position at t=180°",
73                 glm::vec3(-1.0f, 0.0f, 0.0f),
74                 glm::vec3(pos) / pos.w
75         );
76
77         // at 270° position should be (0,0,-sma)
78         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
79         AssertEqual(
80                 "wrong position at t=270°",
81                 glm::vec3(0.0f, 0.0f, 1.0f),
82                 glm::vec3(pos) / pos.w
83         );
84
85         // at 360° position should be (sma,0,0), the initial position
86         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
87         AssertEqual(
88                 "wrong position at t=360°",
89                 glm::vec3(1.0f, 0.0f, 0.0f),
90                 glm::vec3(pos) / pos.w
91         );
92 }
93
94 void OrbitTest::testSMA() {
95         Orbit orbit;
96         orbit.SemiMajorAxis(2.0);
97         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
98                 "wrong semi-major axis on orbit",
99                 2.0, orbit.SemiMajorAxis(), std::numeric_limits<double>::epsilon()
100         );
101
102         // reference direction is +X, so at t=0, the body should be
103         // at (sma,0,0) relative to its parent
104         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
105         AssertEqual(
106                 "wrong position at t=0",
107                 glm::vec3(2.0f, 0.0f, 0.0f),
108                 glm::vec3(pos) / pos.w
109         );
110
111         // at 90° position should be (0,0,sma) since the zero inclination
112         // reference plane is XZ and rotates counter-clockwise
113         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
114         AssertEqual(
115                 "wrong position at t=90°",
116                 glm::vec3(0.0f, 0.0f, -2.0f),
117                 glm::vec3(pos) / pos.w
118         );
119
120         // at 180° position should be (-sma,0,0)
121         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
122         AssertEqual(
123                 "wrong position at t=180°",
124                 glm::vec3(-2.0f, 0.0f, 0.0f),
125                 glm::vec3(pos) / pos.w
126         );
127
128         // at 270° position should be (0,0,-sma)
129         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
130         AssertEqual(
131                 "wrong position at t=270°",
132                 glm::vec3(0.0f, 0.0f, 2.0f),
133                 glm::vec3(pos) / pos.w
134         );
135
136         // at 360° position should be (sma,0,0), the initial position
137         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
138         AssertEqual(
139                 "wrong position at t=360°",
140                 glm::vec3(2.0f, 0.0f, 0.0f),
141                 glm::vec3(pos) / pos.w
142         );
143 }
144
145 void OrbitTest::testEcc() {
146         Orbit orbit;
147         orbit.Eccentricity(0.5);
148         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
149                 "wrong eccentricity on orbit",
150                 0.5, orbit.Eccentricity(), std::numeric_limits<double>::epsilon()
151         );
152
153         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
154         AssertEqual(
155                 "wrong position at t=0",
156                 glm::vec3(0.5f, 0.0f, 0.0f),
157                 glm::vec3(pos) / pos.w
158         );
159
160         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
161         AssertEqual(
162                 "wrong position at t=90°",
163                 glm::vec3(-0.935130834579468f, 0.0f, -0.779740869998932f),
164                 glm::vec3(pos) / pos.w
165         );
166
167         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
168         AssertEqual(
169                 "wrong position at t=180°",
170                 glm::vec3(-1.5f, 0.0f, 0.0f),
171                 glm::vec3(pos) / pos.w
172         );
173
174         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
175         AssertEqual(
176                 "wrong position at t=270°",
177                 glm::vec3(-0.935130834579468f, 0.0f, 0.779740869998932f),
178                 glm::vec3(pos) / pos.w
179         );
180
181         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
182         AssertEqual(
183                 "wrong position at t=360°",
184                 glm::vec3(0.5f, 0.0f, 0.0f),
185                 glm::vec3(pos) / pos.w
186         );
187 }
188
189 void OrbitTest::testInc() {
190         Orbit orbit;
191         orbit.Inclination(PI * 0.25); // 45°
192         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
193                 "wrong inclination on orbit",
194                 PI * 0.25, orbit.Inclination(), std::numeric_limits<double>::epsilon()
195         );
196
197         // inclination rotates counter clockwise around +X, so at t=0 should be
198         // at (sma,0,0) relative to its parent
199         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
200         AssertEqual(
201                 "wrong position at t=0",
202                 glm::vec3(1.0f, 0.0f, 0.0f),
203                 glm::vec3(pos) / pos.w
204         );
205
206         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
207         AssertEqual(
208                 "wrong position at t=90°",
209                 glm::vec3(0.0f, 0.70710676908493f, -0.70710676908493f),
210                 glm::vec3(pos) / pos.w
211         );
212
213         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
214         AssertEqual(
215                 "wrong position at t=180°",
216                 glm::vec3(-1.0f, 0.0f, 0.0f),
217                 glm::vec3(pos) / pos.w
218         );
219
220         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
221         AssertEqual(
222                 "wrong position at t=270°",
223                 glm::vec3(0.0f, -0.70710676908493f, 0.70710676908493f),
224                 glm::vec3(pos) / pos.w
225         );
226
227         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
228         AssertEqual(
229                 "wrong position at t=360°",
230                 glm::vec3(1.0f, 0.0f, 0.0f),
231                 glm::vec3(pos) / pos.w
232         );
233 }
234
235 void OrbitTest::testLngAsc() {
236         Orbit orbit;
237         orbit.LongitudeAscending(PI * 0.25); // 45°
238         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
239                 "wrong longitude of ascending node on orbit",
240                 PI * 0.25, orbit.LongitudeAscending(), std::numeric_limits<double>::epsilon()
241         );
242         // using an inclination of 90° as well to make the rotation more apparent
243         orbit.Inclination(PI * 0.5);
244
245         // inclination rotates counter clockwise around +X, while LAN rotates it
246         // around +Y, so at t=0 should be at (sma*sin(45°),0,-sma*cos(45°))
247         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
248         AssertEqual(
249                 "wrong position at t=0",
250                 glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
251                 glm::vec3(pos) / pos.w
252         );
253
254         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
255         AssertEqual(
256                 "wrong position at t=90°",
257                 glm::vec3(0.0f, 1.0f, 0.0f),
258                 glm::vec3(pos) / pos.w
259         );
260
261         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
262         AssertEqual(
263                 "wrong position at t=180°",
264                 glm::vec3(-0.70710676908493f, 0.0f, 0.70710676908493f),
265                 glm::vec3(pos) / pos.w
266         );
267
268         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
269         AssertEqual(
270                 "wrong position at t=270°",
271                 glm::vec3(0.0f, -1.0f, 0.0f),
272                 glm::vec3(pos) / pos.w
273         );
274
275         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
276         AssertEqual(
277                 "wrong position at t=360°",
278                 glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
279                 glm::vec3(pos) / pos.w
280         );
281 }
282
283 void OrbitTest::testArgPe() {
284         Orbit orbit;
285         orbit.ArgumentPeriapsis(PI * 0.25); // 45°
286         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
287                 "wrong argument of periapsis node on orbit",
288                 PI * 0.25, orbit.ArgumentPeriapsis(), std::numeric_limits<double>::epsilon()
289         );
290         // using an inclination of 90° as well to make the rotation more apparent
291         orbit.Inclination(PI * 0.5);
292
293         // inclination rotates counter clockwise around +X, while APe rotates it
294         // around +Y in the rotated coordinate system, so at t=0 should be at
295         // (sma*sin(45°),0,sma*cos(45°))
296         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
297         AssertEqual(
298                 "wrong position at t=0",
299                 glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f),
300                 glm::vec3(pos) / pos.w
301         );
302
303         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
304         AssertEqual(
305                 "wrong position at t=90°",
306                 glm::vec3(0.0f, 1.0f, 0.0f),
307                 glm::vec3(pos) / pos.w
308         );
309
310         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
311         AssertEqual(
312                 "wrong position at t=180°",
313                 glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f),
314                 glm::vec3(pos) / pos.w
315         );
316
317         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
318         AssertEqual(
319                 "wrong position at t=270°",
320                 glm::vec3(0.0f, -1.0f, 0.0f),
321                 glm::vec3(pos) / pos.w
322         );
323
324         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
325         AssertEqual(
326                 "wrong position at t=360°",
327                 glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f),
328                 glm::vec3(pos) / pos.w
329         );
330 }
331
332 void OrbitTest::testMnAn() {
333         Orbit orbit;
334         orbit.MeanAnomaly(PI * 0.25); // 45°
335         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
336                 "wrong mean anomaly on default orbit",
337                 PI * 0.25, orbit.MeanAnomaly(), std::numeric_limits<double>::epsilon()
338         );
339
340         // mean anomaly just phase shifts the orbit
341         glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
342         AssertEqual(
343                 "wrong position at t=0",
344                 glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
345                 glm::vec3(pos) / pos.w
346         );
347
348         // at 90° position should be (0,0,sma) since the zero inclination
349         // reference plane is XZ and rotates counter-clockwise
350         pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
351         AssertEqual(
352                 "wrong position at t=90°",
353                 glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f),
354                 glm::vec3(pos) / pos.w
355         );
356
357         // at 180° position should be (-sma,0,0)
358         pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
359         AssertEqual(
360                 "wrong position at t=180°",
361                 glm::vec3(-0.70710676908493f, 0.0f, 0.70710676908493f),
362                 glm::vec3(pos) / pos.w
363         );
364
365         // at 270° position should be (0,0,-sma)
366         pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
367         AssertEqual(
368                 "wrong position at t=270°",
369                 glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f),
370                 glm::vec3(pos) / pos.w
371         );
372
373         // at 360° position should be (sma,0,0), the initial position
374         pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
375         AssertEqual(
376                 "wrong position at t=360°",
377                 glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f),
378                 glm::vec3(pos) / pos.w
379         );
380 }
381
382 void OrbitTest::testInverseDefault() {
383         Orbit orbit;
384
385         // inverse matrix should project expected orbit position back to the origin
386         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
387         AssertEqual(
388                 "wrong position at t=0",
389                 glm::vec3(0.0f, 0.0f, 0.0f),
390                 glm::vec3(pos) / pos.w
391         );
392
393         // at 90° position should be (0,0,sma) since the zero inclination
394         // reference plane is XZ and rotates counter-clockwise
395         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
396         AssertEqual(
397                 "wrong position at t=90°",
398                 glm::vec3(0.0f, 0.0f, 0.0f),
399                 glm::vec3(pos) / pos.w
400         );
401
402         // at 180° position should be (-sma,0,0)
403         pos = orbit.InverseMatrix(PI) * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f);
404         AssertEqual(
405                 "wrong position at t=180°",
406                 glm::vec3(0.0f, 0.0f, 0.0f),
407                 glm::vec3(pos) / pos.w
408         );
409
410         // at 270° position should be (0,0,-sma)
411         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
412         AssertEqual(
413                 "wrong position at t=270°",
414                 glm::vec3(0.0f, 0.0f, 0.0f),
415                 glm::vec3(pos) / pos.w
416         );
417
418         // at 360° position should be (sma,0,0), the initial position
419         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
420         AssertEqual(
421                 "wrong position at t=360°",
422                 glm::vec3(0.0f, 0.0f, 0.0f),
423                 glm::vec3(pos) / pos.w
424         );
425 }
426
427 void OrbitTest::testInverseSMA() {
428         Orbit orbit;
429         orbit.SemiMajorAxis(2.0);
430
431         // reference direction is +X, so at t=0, the body should be
432         // at (sma,0,0) relative to its parent
433         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f));
434         AssertEqual(
435                 "wrong position at t=0",
436                 glm::vec3(0.0f, 0.0f, 0.0f),
437                 glm::vec3(pos) / pos.w
438         );
439
440         // at 90° position should be (0,0,sma) since the zero inclination
441         // reference plane is XZ and rotates counter-clockwise
442         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -2.0f, 1.0f);
443         AssertEqual(
444                 "wrong position at t=90°",
445                 glm::vec3(0.0f, 0.0f, 0.0f),
446                 glm::vec3(pos) / pos.w
447         );
448
449         // at 180° position should be (-sma,0,0)
450         pos = orbit.InverseMatrix(PI) * glm::vec4(-2.0f, 0.0f, 0.0f, 1.0f);
451         AssertEqual(
452                 "wrong position at t=180°",
453                 glm::vec3(0.0f, 0.0f, 0.0f),
454                 glm::vec3(pos) / pos.w
455         );
456
457         // at 270° position should be (0,0,-sma)
458         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 2.0f, 1.0f);
459         AssertEqual(
460                 "wrong position at t=270°",
461                 glm::vec3(0.0f, 0.0f, 0.0f),
462                 glm::vec3(pos) / pos.w
463         );
464
465         // at 360° position should be (sma,0,0), the initial position
466         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f);
467         AssertEqual(
468                 "wrong position at t=360°",
469                 glm::vec3(0.0f, 0.0f, 0.0f),
470                 glm::vec3(pos) / pos.w
471         );
472 }
473
474 void OrbitTest::testInverseEcc() {
475         Orbit orbit;
476         orbit.Eccentricity(0.5);
477
478         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f));
479         AssertEqual(
480                 "wrong position at t=0",
481                 glm::vec3(0.0f, 0.0f, 0.0f),
482                 glm::vec3(pos) / pos.w
483         );
484
485         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(-0.935130834579468f, 0.0f, -0.779740869998932f, 1.0f);
486         AssertEqual(
487                 "wrong position at t=90°",
488                 glm::vec3(0.0f, 0.0f, 0.0f),
489                 glm::vec3(pos) / pos.w
490         );
491
492         pos = orbit.InverseMatrix(PI) * glm::vec4(-1.5f, 0.0f, 0.0f, 1.0f);
493         AssertEqual(
494                 "wrong position at t=180°",
495                 glm::vec3(0.0f, 0.0f, 0.0f),
496                 glm::vec3(pos) / pos.w
497         );
498
499         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(-0.935130834579468f, 0.0f, 0.779740869998932f, 1.0f);
500         AssertEqual(
501                 "wrong position at t=270°",
502                 glm::vec3(0.0f, 0.0f, 0.0f),
503                 glm::vec3(pos) / pos.w
504         );
505
506         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f);
507         AssertEqual(
508                 "wrong position at t=360°",
509                 glm::vec3(0.0f, 0.0f, 0.0f),
510                 glm::vec3(pos) / pos.w
511         );
512 }
513
514 void OrbitTest::testInverseInc() {
515         Orbit orbit;
516         orbit.Inclination(PI * 0.25); // 45°
517
518         // inclination rotates counter clockwise around +X, so at t=0 should be
519         // at (sma,0,0) relative to its parent
520         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
521         AssertEqual(
522                 "wrong position at t=0",
523                 glm::vec3(0.0f, 0.0f, 0.0f),
524                 glm::vec3(pos) / pos.w
525         );
526
527         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.70710676908493f, -0.70710676908493f, 1.0f);
528         AssertEqual(
529                 "wrong position at t=90°",
530                 glm::vec3(0.0f, 0.0f, 0.0f),
531                 glm::vec3(pos) / pos.w
532         );
533
534         pos = orbit.InverseMatrix(PI) * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f);
535         AssertEqual(
536                 "wrong position at t=180°",
537                 glm::vec3(0.0f, 0.0f, 0.0f),
538                 glm::vec3(pos) / pos.w
539         );
540
541         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -0.70710676908493f, 0.70710676908493f, 1.0f);
542         AssertEqual(
543                 "wrong position at t=270°",
544                 glm::vec3(0.0f, 0.0f, 0.0f),
545                 glm::vec3(pos) / pos.w
546         );
547
548         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
549         AssertEqual(
550                 "wrong position at t=360°",
551                 glm::vec3(0.0f, 0.0f, 0.0f),
552                 glm::vec3(pos) / pos.w
553         );
554 }
555
556 void OrbitTest::testInverseLngAsc() {
557         Orbit orbit;
558         orbit.LongitudeAscending(PI * 0.25); // 45°
559         orbit.Inclination(PI * 0.5);
560
561         // inclination rotates counter clockwise around +X, while LAN rotates it
562         // around +Y, so at t=0 should be at (sma*sin(45°),0,-sma*cos(45°))
563         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f));
564         AssertEqual(
565                 "wrong position at t=0",
566                 glm::vec3(0.0f, 0.0f, 0.0f),
567                 glm::vec3(pos) / pos.w
568         );
569
570         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
571         AssertEqual(
572                 "wrong position at t=90°",
573                 glm::vec3(0.0f, 0.0f, 0.0f),
574                 glm::vec3(pos) / pos.w
575         );
576
577         pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
578         AssertEqual(
579                 "wrong position at t=180°",
580                 glm::vec3(0.0f, 0.0f, 0.0f),
581                 glm::vec3(pos) / pos.w
582         );
583
584         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
585         AssertEqual(
586                 "wrong position at t=270°",
587                 glm::vec3(0.0f, 0.0f, 0.0f),
588                 glm::vec3(pos) / pos.w
589         );
590
591         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
592         AssertEqual(
593                 "wrong position at t=360°",
594                 glm::vec3(0.0f, 0.0f, 0.0f),
595                 glm::vec3(pos) / pos.w
596         );
597 }
598
599 void OrbitTest::testInverseArgPe() {
600         Orbit orbit;
601         orbit.ArgumentPeriapsis(PI * 0.25); // 45°
602         orbit.Inclination(PI * 0.5);
603
604         // inclination rotates counter clockwise around +X, while APe rotates it
605         // around +Y in the rotated coordinate system, so at t=0 should be at
606         // (sma*sin(45°),0,sma*cos(45°))
607         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f));
608         AssertEqual(
609                 "wrong position at t=0",
610                 glm::vec3(0.0f, 0.0f, 0.0f),
611                 glm::vec3(pos) / pos.w
612         );
613
614         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
615         AssertEqual(
616                 "wrong position at t=90°",
617                 glm::vec3(0.0f, 0.0f, 0.0f),
618                 glm::vec3(pos) / pos.w
619         );
620
621         pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
622         AssertEqual(
623                 "wrong position at t=180°",
624                 glm::vec3(0.0f, 0.0f, 0.0f),
625                 glm::vec3(pos) / pos.w
626         );
627
628         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f);
629         AssertEqual(
630                 "wrong position at t=270°",
631                 glm::vec3(0.0f, 0.0f, 0.0f),
632                 glm::vec3(pos) / pos.w
633         );
634
635         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
636         AssertEqual(
637                 "wrong position at t=360°",
638                 glm::vec3(0.0f, 0.0f, 0.0f),
639                 glm::vec3(pos) / pos.w
640         );
641 }
642
643 void OrbitTest::testInverseMnAn() {
644         Orbit orbit;
645         orbit.MeanAnomaly(PI * 0.25); // 45°
646
647         // mean anomaly just phase shifts the orbit
648         glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f));
649         AssertEqual(
650                 "wrong position at t=0",
651                 glm::vec3(0.0f, 0.0f, 0.0f),
652                 glm::vec3(pos) / pos.w
653         );
654
655         // at 90° position should be (0,0,sma) since the zero inclination
656         // reference plane is XZ and rotates counter-clockwise
657         pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
658         AssertEqual(
659                 "wrong position at t=90°",
660                 glm::vec3(0.0f, 0.0f, 0.0f),
661                 glm::vec3(pos) / pos.w
662         );
663
664         // at 180° position should be (-sma,0,0)
665         pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
666         AssertEqual(
667                 "wrong position at t=180°",
668                 glm::vec3(0.0f, 0.0f, 0.0f),
669                 glm::vec3(pos) / pos.w
670         );
671
672         // at 270° position should be (0,0,-sma)
673         pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f);
674         AssertEqual(
675                 "wrong position at t=270°",
676                 glm::vec3(0.0f, 0.0f, 0.0f),
677                 glm::vec3(pos) / pos.w
678         );
679
680         // at 360° position should be (sma,0,0), the initial position
681         pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f);
682         AssertEqual(
683                 "wrong position at t=360°",
684                 glm::vec3(0.0f, 0.0f, 0.0f),
685                 glm::vec3(pos) / pos.w
686         );
687 }
688 }
689 }
690 }