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