]> git.localhorst.tv Git - blank.git/blob - tst/net/PacketTest.cpp
split geometry lib
[blank.git] / tst / net / PacketTest.cpp
1 #include "PacketTest.hpp"
2
3 #include "geometry/const.hpp"
4 #include "model/Model.hpp"
5 #include "world/Entity.hpp"
6
7 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::PacketTest);
8
9 using namespace std;
10
11 namespace blank {
12 namespace test {
13
14 void PacketTest::setUp() {
15         udp_pack.data = new Uint8[sizeof(Packet)];
16         udp_pack.maxlen = sizeof(Packet);
17 }
18
19 void PacketTest::tearDown() {
20         delete[] udp_pack.data;
21 }
22
23 namespace {
24
25 static constexpr uint32_t TEST_TAG = 0xFB1AB1AF;
26
27 }
28
29 void PacketTest::testSizes() {
30         CPPUNIT_ASSERT_EQUAL_MESSAGE(
31                 "unexpected size of vec3",
32                 size_t(12), sizeof(glm::vec3)
33         );
34         CPPUNIT_ASSERT_EQUAL_MESSAGE(
35                 "unexpected size of vec3i",
36                 size_t(12), sizeof(glm::ivec3)
37         );
38 }
39
40 void PacketTest::testControl() {
41         Packet::TControl ctrl{ 0, 10, 0 };
42
43         CPPUNIT_ASSERT_MESSAGE(
44                 "TControl should ack the packet in the ack field",
45                 ctrl.Acks(10)
46         );
47         CPPUNIT_ASSERT_MESSAGE(
48                 "TControl should ack the packet in the future",
49                 !ctrl.Acks(11)
50         );
51         CPPUNIT_ASSERT_MESSAGE(
52                 "TControl should not ack a packet in the distant past",
53                 !ctrl.Acks(-30)
54         );
55         CPPUNIT_ASSERT_MESSAGE(
56                 "TControl should not ack the previous packet if the bitfield is 0",
57                 !ctrl.Acks(9)
58         );
59         CPPUNIT_ASSERT_EQUAL_MESSAGE(
60                 "TControl's acks should begin at the packet in the ack field",
61                 uint16_t(10), ctrl.AckBegin()
62         );
63         CPPUNIT_ASSERT_EQUAL_MESSAGE(
64                 "TControl's acks should end 33 packets before the one in the ack field",
65                 uint16_t(-23), ctrl.AckEnd()
66         );
67         ctrl.hist = 1;
68         CPPUNIT_ASSERT_MESSAGE(
69                 "TControl should ack the previous packet if the bitfield is 1",
70                 ctrl.Acks(9)
71         );
72         ctrl.hist = 2;
73         CPPUNIT_ASSERT_MESSAGE(
74                 "TControl should not ack the previous packet if the bitfield is 2",
75                 !ctrl.Acks(9)
76         );
77         CPPUNIT_ASSERT_MESSAGE(
78                 "TControl should ack the packet before the previous one if the bitfield is 2",
79                 ctrl.Acks(8)
80         );
81 }
82
83 void PacketTest::testPing() {
84         auto pack = Packet::Make<Packet::Ping>(udp_pack);
85         AssertPacket("Ping", 0, 0, pack);
86 }
87
88 void PacketTest::testLogin() {
89         auto pack = Packet::Make<Packet::Login>(udp_pack);
90         AssertPacket("Login", 1, 0, 32, pack);
91
92         string write_name = "test";
93         string read_name;
94         pack.WritePlayerName(write_name);
95         pack.ReadPlayerName(read_name);
96         CPPUNIT_ASSERT_EQUAL_MESSAGE(
97                 "player name not correctly transported in Login packet",
98                 write_name, read_name
99         );
100
101         write_name = "0123456789012345678901234567890123456789";
102         pack.WritePlayerName(write_name);
103         pack.ReadPlayerName(read_name);
104         CPPUNIT_ASSERT_EQUAL_MESSAGE(
105                 "player name not correctly truncated in Login packet",
106                 write_name.substr(0, 32), read_name
107         );
108 }
109
110 void PacketTest::testJoin() {
111         auto pack = Packet::Make<Packet::Join>(udp_pack);
112         AssertPacket("Join", 2, 47, 78, pack);
113
114         Entity write_entity;
115         write_entity.ID(534574);
116         EntityState write_state;
117         write_state.chunk_pos = { 7, 2, -3 };
118         write_state.block_pos = { 1.5f, 0.9f, 12.0f };
119         write_state.velocity = { 0.025f, 0.001f, 0.0f };
120         write_state.orient = { 1.0f, 0.0f, 0.0f, 0.0f };
121         write_state.pitch = 0.3f;
122         write_state.yaw = -2.3f;
123         write_entity.SetState(write_state);
124         uint32_t read_id = 0;
125         EntityState read_state;
126         pack.WritePlayer(write_entity);
127
128         pack.ReadPlayerID(read_id);
129         CPPUNIT_ASSERT_EQUAL_MESSAGE(
130                 "player entity ID not correctly transported in Join packet",
131                 write_entity.ID(), read_id
132         );
133         pack.ReadPlayerState(read_state);
134         AssertEqual(
135                 "player entity state not correctly transported in Join packet",
136                 write_entity.GetState(), read_state
137         );
138
139         string write_name = "test";
140         string read_name;
141         pack.WriteWorldName(write_name);
142         pack.ReadWorldName(read_name);
143         CPPUNIT_ASSERT_EQUAL_MESSAGE(
144                 "world name not correctly transported in Join packet",
145                 write_name, read_name
146         );
147
148         write_name = "0123456789012345678901234567890123456789";
149         pack.WriteWorldName(write_name);
150         pack.ReadWorldName(read_name);
151         CPPUNIT_ASSERT_EQUAL_MESSAGE(
152                 "world name not correctly truncated in Join packet",
153                 write_name.substr(0, 32), read_name
154         );
155 }
156
157 void PacketTest::testPart() {
158         auto pack = Packet::Make<Packet::Part>(udp_pack);
159         AssertPacket("Part", 3, 0, pack);
160 }
161
162 void PacketTest::testPlayerUpdate() {
163         auto pack = Packet::Make<Packet::PlayerUpdate>(udp_pack);
164         AssertPacket("PlayerUpdate", 4, 50, pack);
165
166         EntityState write_state;
167         write_state.chunk_pos = { 7, 2, -3 };
168         write_state.block_pos = { 1.5f, 0.9f, 12.0f };
169         write_state.velocity = { 0.025f, 0.001f, 0.0f };
170         write_state.orient = { 1.0f, 0.0f, 0.0f, 0.0f };
171         glm::vec3 write_movement(0.5f, -1.0f, 1.0f);
172         uint8_t write_actions = 0x05;
173         uint8_t write_slot = 3;
174         pack.WritePredictedState(write_state);
175         pack.WriteMovement(write_movement);
176         pack.WriteActions(write_actions);
177         pack.WriteSlot(write_slot);
178
179         EntityState read_state;
180         glm::vec3 read_movement;
181         uint8_t read_actions;
182         uint8_t read_slot;
183         pack.ReadPredictedState(read_state);
184         pack.ReadMovement(read_movement);
185         pack.ReadActions(read_actions);
186         pack.ReadSlot(read_slot);
187         AssertEqual(
188                 "player predicted entity state not correctly transported in PlayerUpdate packet",
189                 write_state, read_state
190         );
191         AssertEqual(
192                 "player movement input not correctly transported in PlayerUpdate packet",
193                 write_movement, read_movement, 0.0001f
194         );
195         CPPUNIT_ASSERT_EQUAL_MESSAGE(
196                 "player actions not correctly transported in PlayerUpdate packet",
197                 int(write_actions), int(read_actions)
198         );
199         CPPUNIT_ASSERT_EQUAL_MESSAGE(
200                 "player inventory slot not correctly transported in PlayerUpdate packet",
201                 int(write_slot), int(read_slot)
202         );
203 }
204
205 void PacketTest::testSpawnEntity() {
206         auto pack = Packet::Make<Packet::SpawnEntity>(udp_pack);
207         AssertPacket("SpawnEntity", 5, 79, 110, pack);
208
209         Entity write_entity;
210         write_entity.ID(534574);
211         Model model;
212         model.ID(23);
213         model.Enumerate();
214         model.Instantiate(write_entity.GetModel());
215         EntityState write_state;
216         write_state.chunk_pos = { 7, 2, -3 };
217         write_state.block_pos = { 1.5f, 0.9f, 12.0f };
218         write_state.velocity = { 0.025f, 0.001f, 0.0f };
219         write_state.pitch = 0.3f;
220         write_state.yaw = -2.3f;
221         write_entity.SetState(write_state);
222         write_entity.Bounds({{ -1, -1, -1 }, { 1, 1, 1 }});
223         write_entity.WorldCollidable(true);
224         write_entity.Name("blah");
225         pack.WriteEntity(write_entity);
226
227         uint32_t entity_id;
228         uint32_t model_id;
229         Entity read_entity;
230         pack.ReadEntityID(entity_id);
231         pack.ReadModelID(model_id);
232         pack.ReadEntity(read_entity);
233
234         CPPUNIT_ASSERT_EQUAL_MESSAGE(
235                 "entity ID not correctly transported in SpawnEntity packet",
236                 write_entity.ID(), entity_id
237         );
238         CPPUNIT_ASSERT_EQUAL_MESSAGE(
239                 "model ID not correctly transported in SpawnEntity packet",
240                 write_entity.GetModel().GetModel().ID(), model_id
241         );
242         AssertEqual(
243                 "entity state not correctly transported in PlayerUpdate packet",
244                 write_entity.GetState(), read_entity.GetState()
245         );
246         AssertEqual(
247                 "entity bounds not correctly transported in PlayerUpdate packet",
248                 write_entity.Bounds(), read_entity.Bounds()
249         );
250         CPPUNIT_ASSERT_MESSAGE(
251                 "entity flags not correctly transported in SpawnEntity packet",
252                 read_entity.WorldCollidable()
253         );
254         CPPUNIT_ASSERT_EQUAL_MESSAGE(
255                 "entity name not correctly transported in SpawnEntity packet",
256                 write_entity.Name(), read_entity.Name()
257         );
258 }
259
260 void PacketTest::testDespawnEntity() {
261         auto pack = Packet::Make<Packet::DespawnEntity>(udp_pack);
262         AssertPacket("DespawnEntity", 6, 4, pack);
263
264         uint32_t write_id = 5437;
265         uint32_t read_id;
266         pack.WriteEntityID(write_id);
267         pack.ReadEntityID(read_id);
268
269         CPPUNIT_ASSERT_EQUAL_MESSAGE(
270                 "entity ID not correctly transported in DespawnEntity packet",
271                 write_id, read_id
272         );
273 }
274
275 void PacketTest::testEntityUpdate() {
276         auto pack = Packet::Make<Packet::EntityUpdate>(udp_pack);
277         AssertPacket("EntityUpdate", 7, 16, 460, pack);
278
279         pack.length = Packet::EntityUpdate::GetSize(3);
280         CPPUNIT_ASSERT_EQUAL_MESSAGE(
281                 "length not correctly set in EntityUpdate packet",
282                 size_t(16 + 3 * 37), pack.length
283         );
284
285         uint32_t write_count = 3;
286         glm::ivec3 write_base(8, -15, 1);
287         pack.WriteEntityCount(write_count);
288         pack.WriteChunkBase(write_base);
289
290         uint32_t read_count;
291         glm::ivec3 read_base;
292         pack.ReadEntityCount(read_count);
293         pack.ReadChunkBase(read_base);
294
295         CPPUNIT_ASSERT_EQUAL_MESSAGE(
296                 "entity count not correctly transported in EntityUpdate packet",
297                 write_count, read_count
298         );
299         AssertEqual(
300                 "chunk base not correctly transported in EntityUpdate packet",
301                 write_base, read_base
302         );
303
304         Entity write_entity;
305         write_entity.ID(8567234);
306         EntityState write_state;
307         write_state.chunk_pos = { 7, 2, -3 };
308         write_state.block_pos = { 1.5f, 0.9f, 12.0f };
309         write_state.velocity = { 0.025f, 0.001f, 0.0f };
310         write_state.pitch = 0.3f;
311         write_state.yaw = -2.3f;
312         write_entity.SetState(write_state);
313         pack.WriteEntity(write_entity, write_base, 1);
314         pack.WriteEntity(write_entity, write_base, 0);
315         pack.WriteEntity(write_entity, write_base, 2);
316
317         uint32_t read_id;
318         EntityState read_state;
319         pack.ReadEntityID(read_id, 1);
320         pack.ReadEntityState(read_state, write_base, 1);
321         CPPUNIT_ASSERT_EQUAL_MESSAGE(
322                 "entity ID not correctly transported in EntityUpdate packet",
323                 write_entity.ID(), read_id
324         );
325         AssertEqual(
326                 "entity state not correctly transported in EntityUpdate packet",
327                 write_entity.GetState(), read_state
328         );
329 }
330
331 void PacketTest::testPlayerCorrection() {
332         auto pack = Packet::Make<Packet::PlayerCorrection>(udp_pack);
333         AssertPacket("PlayerCorrection", 8, 44, pack);
334
335         uint16_t write_seq = 50050;
336         uint16_t read_seq;
337         pack.WritePacketSeq(write_seq);
338         pack.ReadPacketSeq(read_seq);
339         CPPUNIT_ASSERT_EQUAL_MESSAGE(
340                 "packet sequence not correctly transported in PlayerCorrection packet",
341                 write_seq, read_seq
342         );
343
344         Entity write_entity;
345         EntityState write_state;
346         write_state.chunk_pos = { 7, 2, -3 };
347         write_state.block_pos = { 1.5f, 0.9f, 12.0f };
348         write_state.velocity = { 0.025f, 0.001f, 0.0f };
349         write_state.pitch = 0.3f;
350         write_state.yaw = -2.3f;
351         write_entity.SetState(write_state);
352         pack.WritePlayer(write_entity);
353
354         EntityState read_state;
355         pack.ReadPlayerState(read_state);
356         AssertEqual(
357                 "entity state not correctly transported in PlayerCorrection packet",
358                 write_entity.GetState(), read_state
359         );
360 }
361
362 void PacketTest::testChunkBegin() {
363         auto pack = Packet::Make<Packet::ChunkBegin>(udp_pack);
364         AssertPacket("ChunkBegin", 9, 24, pack);
365
366         uint32_t write_id = 532;
367         uint32_t write_flags = 9864328;
368         glm::ivec3 write_pos = { -6, 15, 38 };
369         uint32_t write_size = 4097;
370
371         pack.WriteTransmissionId(write_id);
372         pack.WriteFlags(write_flags);
373         pack.WriteChunkCoords(write_pos);
374         pack.WriteDataSize(write_size);
375
376         uint32_t read_id;
377         uint32_t read_flags;
378         glm::ivec3 read_pos;
379         uint32_t read_size;
380
381         pack.ReadTransmissionId(read_id);
382         pack.ReadFlags(read_flags);
383         pack.ReadChunkCoords(read_pos);
384         pack.ReadDataSize(read_size);
385
386         CPPUNIT_ASSERT_EQUAL_MESSAGE(
387                 "transmission ID not correctly transported in ChunkBegin packet",
388                 write_id, read_id
389         );
390         CPPUNIT_ASSERT_EQUAL_MESSAGE(
391                 "flags not correctly transported in ChunkBegin packet",
392                 write_flags, read_flags
393         );
394         AssertEqual(
395                 "chunk coordinates not correctly transported in ChunkBegin packet",
396                 write_pos, read_pos
397         );
398         CPPUNIT_ASSERT_EQUAL_MESSAGE(
399                 "data size not correctly transported in ChunkBegin packet",
400                 write_size, read_size
401         );
402 }
403
404 void PacketTest::testChunkData() {
405         auto pack = Packet::Make<Packet::ChunkData>(udp_pack);
406         AssertPacket("ChunkData", 10, 12, 484, pack);
407
408         constexpr size_t block_size = 97;
409
410         uint32_t write_id = 6743124;
411         uint32_t write_offset = 8583;
412         uint32_t write_size = block_size;
413         uint8_t write_data[block_size];
414         memset(write_data, 'X', block_size);
415
416         pack.WriteTransmissionId(write_id);
417         pack.WriteDataOffset(write_offset);
418         pack.WriteDataSize(write_size);
419         pack.WriteData(write_data, write_size);
420
421         uint32_t read_id;
422         uint32_t read_offset;
423         uint32_t read_size;
424         uint8_t read_data[block_size];
425
426         pack.ReadTransmissionId(read_id);
427         pack.ReadDataOffset(read_offset);
428         pack.ReadDataSize(read_size);
429         pack.ReadData(read_data, read_size);
430
431         CPPUNIT_ASSERT_EQUAL_MESSAGE(
432                 "transmission ID not correctly transported in ChunkData packet",
433                 write_id, read_id
434         );
435         CPPUNIT_ASSERT_EQUAL_MESSAGE(
436                 "data offset not correctly transported in ChunkData packet",
437                 write_offset, read_offset
438         );
439         CPPUNIT_ASSERT_EQUAL_MESSAGE(
440                 "data size not correctly transported in ChunkData packet",
441                 write_size, read_size
442         );
443         CPPUNIT_ASSERT_EQUAL_MESSAGE(
444                 "raw data not correctly transported in ChunkData packet",
445                 string(write_data, write_data + write_size), string(read_data, read_data + read_size)
446         );
447 }
448
449 void PacketTest::testBlockUpdate() {
450         auto pack = Packet::Make<Packet::BlockUpdate>(udp_pack);
451         AssertPacket("BlockUpdate", 11, 16, 484, pack);
452
453         pack.length = Packet::BlockUpdate::GetSize(3);
454         CPPUNIT_ASSERT_EQUAL_MESSAGE(
455                 "length not correctly set in BlockUpdate packet",
456                 size_t(16 + 3 * 6), pack.length
457         );
458
459         glm::ivec3 write_coords(432, -325, 99998);
460         uint32_t write_count = 3;
461         uint16_t write_index = 432;
462         Block write_block(324, Block::FACE_DOWN, Block::TURN_AROUND);
463
464         pack.WriteChunkCoords(write_coords);
465         pack.WriteBlockCount(write_count);
466         pack.WriteIndex(write_index, 1);
467         pack.WriteBlock(write_block, 1);
468         pack.WriteIndex(write_index, 0);
469         pack.WriteBlock(write_block, 0);
470         pack.WriteIndex(write_index, 2);
471         pack.WriteBlock(write_block, 2);
472
473         glm::ivec3 read_coords;
474         uint32_t read_count;
475         uint16_t read_index;
476         Block read_block;
477
478         pack.ReadChunkCoords(read_coords);
479         pack.ReadBlockCount(read_count);
480         pack.ReadIndex(read_index, 1);
481         pack.ReadBlock(read_block, 1);
482
483         AssertEqual(
484                 "chunk coordinates not correctly transported in BlockUpdate packet",
485                 write_coords, read_coords
486         );
487         CPPUNIT_ASSERT_EQUAL_MESSAGE(
488                 "block count not correctly transported in BlockUpdate packet",
489                 write_count, read_count
490         );
491         CPPUNIT_ASSERT_EQUAL_MESSAGE(
492                 "block index not correctly transported in BlockUpdate packet",
493                 write_index, read_index
494         );
495         CPPUNIT_ASSERT_EQUAL_MESSAGE(
496                 "block type not correctly transported in BlockUpdate packet",
497                 write_block.type, read_block.type
498         );
499         CPPUNIT_ASSERT_EQUAL_MESSAGE(
500                 "block face not correctly transported in BlockUpdate packet",
501                 write_block.GetFace(), read_block.GetFace()
502         );
503         CPPUNIT_ASSERT_EQUAL_MESSAGE(
504                 "block turn not correctly transported in BlockUpdate packet",
505                 write_block.GetTurn(), read_block.GetTurn()
506         );
507 }
508
509 void PacketTest::testMessage() {
510         auto pack = Packet::Make<Packet::Message>(udp_pack);
511         AssertPacket("Message", 12, 6, 455, pack);
512
513         const uint8_t write_type = 1;
514         const uint32_t write_ref = 6433235;
515         const string write_msg("hello, world");
516
517         pack.length = Packet::Message::GetSize(write_msg);
518         CPPUNIT_ASSERT_EQUAL_MESSAGE(
519                 "length not correctly set in BlockUpdate packet",
520                 size_t(5 + write_msg.size() + 1), pack.length
521         );
522
523         pack.WriteType(write_type);
524         pack.WriteReferral(write_ref);
525         pack.WriteMessage(write_msg);
526
527         uint8_t read_type = 5;
528         uint32_t read_ref = 884373;
529         string read_msg;
530
531         pack.ReadType(read_type);
532         pack.ReadReferral(read_ref);
533         pack.ReadMessage(read_msg);
534
535         CPPUNIT_ASSERT_EQUAL_MESSAGE(
536                 "type not correctly transported in Message packet",
537                 write_type, read_type
538         );
539         CPPUNIT_ASSERT_EQUAL_MESSAGE(
540                 "referral not correctly transported in Message packet",
541                 write_ref, read_ref
542         );
543         CPPUNIT_ASSERT_EQUAL_MESSAGE(
544                 "message not correctly transported in Message packet",
545                 write_msg, read_msg
546         );
547 }
548
549
550 void PacketTest::AssertPacket(
551         const string &name,
552         uint8_t expected_type,
553         size_t expected_length,
554         const Packet::Payload &actual
555 ) {
556         CPPUNIT_ASSERT_EQUAL_MESSAGE(
557                 name + " packet not correctly tagged",
558                 TEST_TAG, actual.GetHeader().tag
559         );
560         CPPUNIT_ASSERT_EQUAL_MESSAGE(
561                 "wrong type code for " + name + " packet",
562                 int(expected_type), int(actual.GetHeader().type)
563         );
564         CPPUNIT_ASSERT_EQUAL_MESSAGE(
565                 "bad payload length for " + name + " packet",
566                 expected_length, actual.length
567         );
568 }
569
570 void PacketTest::AssertPacket(
571         const string &name,
572         uint8_t expected_type,
573         size_t min_length,
574         size_t max_length,
575         const Packet::Payload &actual
576 ) {
577         CPPUNIT_ASSERT_EQUAL_MESSAGE(
578                 name + " packet not correctly tagged",
579                 TEST_TAG, actual.GetHeader().tag
580         );
581         CPPUNIT_ASSERT_EQUAL_MESSAGE(
582                 "wrong type code for " + name + " packet",
583                 expected_type, actual.GetHeader().type
584         );
585         CPPUNIT_ASSERT_MESSAGE(
586                 "bad payload length for " + name + " packet",
587                 actual.length >= min_length && actual.length <= max_length
588         );
589 }
590
591 void PacketTest::AssertEqual(
592         const string &message,
593         const EntityState &expected,
594         const EntityState &actual
595 ) {
596         AssertEqual(
597                 message + ": bad chunk position",
598                 expected.chunk_pos, actual.chunk_pos
599         );
600         AssertEqual(
601                 message + ": bad block position",
602                 expected.block_pos, actual.block_pos, 16.0f/65535.0f // that's about the max accuracy that packing's going to give us
603         );
604         AssertEqual(
605                 message + ": bad velocity",
606                 expected.velocity, actual.velocity
607         );
608         AssertEqual(
609                 message + ": bad orientation",
610                 expected.orient, actual.orient
611         );
612         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
613                 message + ": bad pitch",
614                 expected.pitch, actual.pitch, PI/65534.0f
615         );
616         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
617                 message + ": bad yaw",
618                 expected.yaw, actual.yaw, PI/32767.0f
619         );
620 }
621
622 void PacketTest::AssertEqual(
623         const string &message,
624         const AABB &expected,
625         const AABB &actual
626 ) {
627         AssertEqual(
628                 message + ": bad lower bound",
629                 expected.min, actual.min
630         );
631         AssertEqual(
632                 message + ": bad upper bound",
633                 expected.max, actual.max
634         );
635 }
636
637 void PacketTest::AssertEqual(
638         const string &message,
639         const glm::ivec3 &expected,
640         const glm::ivec3 &actual
641 ) {
642         CPPUNIT_ASSERT_EQUAL_MESSAGE(
643                 message + " (X component)",
644                 expected.x, actual.x
645         );
646         CPPUNIT_ASSERT_EQUAL_MESSAGE(
647                 message + " (Y component)",
648                 expected.y, actual.y
649         );
650         CPPUNIT_ASSERT_EQUAL_MESSAGE(
651                 message + " (Z component)",
652                 expected.z, actual.z
653         );
654 }
655
656 void PacketTest::AssertEqual(
657         const string &message,
658         const glm::vec3 &expected,
659         const glm::vec3 &actual,
660         float epsilon
661 ) {
662         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
663                 message + " (X component)",
664                 expected.x, actual.x, epsilon
665         );
666         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
667                 message + " (Y component)",
668                 expected.y, actual.y, epsilon
669         );
670         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
671                 message + " (Z component)",
672                 expected.z, actual.z, epsilon
673         );
674 }
675
676 void PacketTest::AssertEqual(
677         const string &message,
678         const glm::quat &expected,
679         const glm::quat &actual
680 ) {
681         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
682                 message + " (W component)",
683                 expected.w, actual.w, (1.0f / 32767.0f)
684         );
685         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
686                 message + " (X component)",
687                 expected.x, actual.x, (1.0f / 32767.0f)
688         );
689         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
690                 message + " (Y component)",
691                 expected.y, actual.y, (1.0f / 32767.0f)
692         );
693         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
694                 message + " (Z component)",
695                 expected.z, actual.z, (1.0f / 32767.0f)
696         );
697 }
698
699 }
700 }