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