]> git.localhorst.tv Git - blank.git/commitdiff
compress protocol a little
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 21 Oct 2015 12:47:14 +0000 (14:47 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 21 Oct 2015 12:47:14 +0000 (14:47 +0200)
doc/protocol
src/client/client.cpp
src/model/geometry.hpp
src/net/Packet.hpp
src/net/net.cpp
src/server/net.cpp
tst/net/PacketTest.cpp

index 102bf50d745769f004f8c282efefb66d0daf95f9..1cea7804220573bb6a465accee2b70be330cc55a 100644 (file)
@@ -23,8 +23,19 @@ Common Types
 Name          Size  Type
 vec3          12    3x 32bit float
 vec3i         12    3x 32bit signed int
 Name          Size  Type
 vec3          12    3x 32bit float
 vec3i         12    3x 32bit signed int
-quat          16    4x 32bit float
-entity state  64    vec3i, vec3, vec3, quat, vec3
+vec3b          3    3x 8bit signed int
+packn          2    16bit signed int representing a float value normalized to [-1,1]
+                       it can be unpacked by dividing by 32767
+packu          2    16bit unsigned  int representing a float value normalized to [0,1]
+                       it can be unpacked by dividing by 65535
+vec3n          6    3x packn
+vec3u          6    3x packu
+quat           8    4x packn float
+entity state  50    [ 0] vec3i chunk pos (there's a variation where this is a vec3b)
+                    [12] vec3u block pos by 16,
+                    [18] vec3 velocity,
+                    [30] quat orientation,
+                    [38] vec3 angular velocity
 
 
 Packets
 
 
 Packets
@@ -45,7 +56,7 @@ Length: 0
 Login
 -----
 
 Login
 -----
 
-Sent from client to serveri as a request to join. The server may
+Sent from client to server as a request to join. The server may
 respond negatively if the player name is already taken or some cap has
 been reached.
 
 respond negatively if the player name is already taken or some cap has
 been reached.
 
@@ -66,9 +77,9 @@ Code: 2
 Payload:
         0 entity ID of the player, 32bit unsigned int
         4 entity state of the player
 Payload:
         0 entity ID of the player, 32bit unsigned int
         4 entity state of the player
-       68 name of the world the server's currently running
+       54 name of the world the server's currently running
           max 32 byte UTF-8 string
           max 32 byte UTF-8 string
-Length: 68-100
+Length: 54-86
 
 
 Part
 
 
 Part
@@ -91,12 +102,12 @@ Sent by clients to notify the server of their changes to the player.
 Code: 4
 Payload:
         0 player's entity state as predicted by the client
 Code: 4
 Payload:
         0 player's entity state as predicted by the client
-       64 movement input, 3x 16bit signed int, each component mapped from [-1,1] to [-32767,32767]
-       70 pitch input, 16bit signed int, mapped from [-PI/2,PI/2] to [-32767,32767]
-       72 yaw input, 16bit signed int, mapped from [-PI,PI] to [-32767,32767]
-       74 active actions, 8bit bit field, first three bits are primary, secondary, and tertiary
-       75 selected inventory slot, 8bit unsigned int
-Length: 76
+       50 movement input, vec3n
+       56 pitch input by PI/2, packn
+       58 yaw input by PI, packn
+       60 active actions, 8bit bit field, first three bits are primary, secondary, and tertiary
+       61 selected inventory slot, 8bit unsigned int
+Length: 62
 
 
 Spawn Entity
 
 
 Spawn Entity
@@ -106,14 +117,14 @@ Sent by the server to notify the client of an entity entering spawn range.
 
 Code: 5
 Payload:
 
 Code: 5
 Payload:
-         0 entity ID, 32bit unsigned int
-         4 entity's skeleton ID, 32bit unsigned int
-         8 entity state
-        72 bounding box of the entity, 6x 32bit float
-        96 flags, 32bit bitfield with boolean values
-           1: world collision
-       100 entity name, max 32 byte UTF-8 string
-Length: 100 - 132
+        0 entity ID, 32bit unsigned int
+        4 entity's model ID, 32bit unsigned int
+        8 entity state
+       58 bounding box of the entity, 6x 32bit float
+       82 flags, 32bit bitfield with boolean values
+          1: world collision
+       86 entity name, max 32 byte UTF-8 string
+Length: 87 - 118
 
 
 Despawn Entity
 
 
 Despawn Entity
@@ -135,11 +146,12 @@ Contained entities must be ordered by ascending entity ID.
 
 Code: 7
 Payload:
 
 Code: 7
 Payload:
-        0 number of entities, 32bit int, 1-7
-        4 entity ID, 32bit unsigned int
-        8 entity state
-       72 next entity...
-Length: 4 + multiple of 68, max 480
+        0 number of entities, 32bit int, 1-10
+        4 base for chunk coordinates, vec3i
+       16 entity ID, 32bit unsigned int
+       20 entity state with vec3b as chunk position (rather than vec3i)
+       62 next entity...
+Length: 16 + multiple of 45, max 466
 
 
 Player Correction
 
 
 Player Correction
@@ -151,7 +163,7 @@ Code: 8
 Payload:
         0 sequence number of the offending packet, 16bit unsigned int
         2 entity state of the player's entity on the server
 Payload:
         0 sequence number of the offending packet, 16bit unsigned int
         2 entity state of the player's entity on the server
-Length: 66
+Length: 52
 
 
 Chunk Begin
 
 
 Chunk Begin
index 44163f6cc17b74b9cb548b3bd93242e6028b6a90..773c0be595e06fd95f06aa410bf062c7d0d225f6 100644 (file)
@@ -171,11 +171,10 @@ void InteractiveState::Handle(const Packet::SpawnEntity &pack) {
        Entity &entity = world.ForceAddEntity(entity_id);
        UpdateEntity(entity_id, pack.Seq());
        pack.ReadEntity(entity);
        Entity &entity = world.ForceAddEntity(entity_id);
        UpdateEntity(entity_id, pack.Seq());
        pack.ReadEntity(entity);
-       uint32_t skel_id;
-       pack.ReadSkeletonID(skel_id);
-       if (skel_id > 0 && skel_id <= res.models.size()) {
-               Model &skel = res.models.Get(skel_id);
-               skel.Instantiate(entity.GetModel());
+       uint32_t model_id;
+       pack.ReadModelID(model_id);
+       if (model_id > 0 && model_id <= res.models.size()) {
+               res.models.Get(model_id).Instantiate(entity.GetModel());
        }
        cout << "spawned entity #" << entity_id << "  (" << entity.Name()
                << ") at " << entity.AbsolutePosition() << endl;
        }
        cout << "spawned entity #" << entity_id << "  (" << entity.Name()
                << ") at " << entity.AbsolutePosition() << endl;
@@ -199,7 +198,9 @@ void InteractiveState::Handle(const Packet::EntityUpdate &pack) {
        auto world_end = world.Entities().end();
 
        uint32_t count = 0;
        auto world_end = world.Entities().end();
 
        uint32_t count = 0;
+       glm::ivec3 base;
        pack.ReadEntityCount(count);
        pack.ReadEntityCount(count);
+       pack.ReadChunkBase(base);
 
        for (uint32_t i = 0; i < count; ++i) {
                uint32_t entity_id = 0;
 
        for (uint32_t i = 0; i < count; ++i) {
                uint32_t entity_id = 0;
@@ -214,7 +215,7 @@ void InteractiveState::Handle(const Packet::EntityUpdate &pack) {
                }
                if (world_iter->ID() == entity_id) {
                        if (UpdateEntity(entity_id, pack.Seq())) {
                }
                if (world_iter->ID() == entity_id) {
                        if (UpdateEntity(entity_id, pack.Seq())) {
-                               pack.ReadEntityState(world_iter->GetState(), i);
+                               pack.ReadEntityState(world_iter->GetState(), base, i);
                        }
                }
        }
                        }
                }
        }
index f9f87c4f9d14462f31af92b16247e5a6aad584e9..fd2c42bb8c8fa7f643f7fcae8697aeac26496dd2 100644 (file)
@@ -13,6 +13,9 @@ constexpr float PI_0p5 = PI * 0.5f;
 constexpr float PI_1p5 = PI * 1.5f;
 constexpr float PI_2p0 = PI * 2.0f;
 
 constexpr float PI_1p5 = PI * 1.5f;
 constexpr float PI_2p0 = PI * 2.0f;
 
+constexpr float PI_inv = 1.0f / PI;
+constexpr float PI_0p5_inv = 1.0f / PI_0p5;
+
 constexpr float DEG_RAD_FACTOR = PI / 180.0f;
 constexpr float RAD_DEG_FACTOR = 180.0f / PI;
 
 constexpr float DEG_RAD_FACTOR = PI / 180.0f;
 constexpr float RAD_DEG_FACTOR = 180.0f / PI;
 
index c9184d47000b40e5252d296619176f0c6c3185d4..a6a9d54c478894e02129c893d5ff57ad2d1be0de 100644 (file)
@@ -73,8 +73,28 @@ struct Packet {
                template<class T>
                void Read(T &, size_t off) const noexcept;
 
                template<class T>
                void Read(T &, size_t off) const noexcept;
 
+               void Write(const glm::quat &, size_t off) noexcept;
+               void Read(glm::quat &, size_t off) const noexcept;
+               void Write(const EntityState &, size_t off) noexcept;
+               void Read(EntityState &, size_t off) const noexcept;
+               void Write(const EntityState &, const glm::ivec3 &, size_t off) noexcept;
+               void Read(EntityState &, const glm::ivec3 &, size_t off) const noexcept;
+
                void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
                void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
                void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
                void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
+
+               void WritePackB(const glm::ivec3 &, size_t off) noexcept;
+               void ReadPackB(glm::ivec3 &, size_t off) const noexcept;
+
+               void WritePackN(float, size_t off) noexcept;
+               void ReadPackN(float &, size_t off) const noexcept;
+               void WritePackN(const glm::vec3 &, size_t off) noexcept;
+               void ReadPackN(glm::vec3 &, size_t off) const noexcept;
+
+               void WritePackU(float, size_t off) noexcept;
+               void ReadPackU(float &, size_t off) const noexcept;
+               void WritePackU(const glm::vec3 &, size_t off) noexcept;
+               void ReadPackU(glm::vec3 &, size_t off) const noexcept;
        };
 
        struct Ping : public Payload {
        };
 
        struct Ping : public Payload {
@@ -92,7 +112,7 @@ struct Packet {
 
        struct Join : public Payload {
                static constexpr std::uint8_t TYPE = 2;
 
        struct Join : public Payload {
                static constexpr std::uint8_t TYPE = 2;
-               static constexpr std::size_t MAX_LEN = 100;
+               static constexpr std::size_t MAX_LEN = 86;
 
                void WritePlayer(const Entity &) noexcept;
                void ReadPlayerID(std::uint32_t &) const noexcept;
 
                void WritePlayer(const Entity &) noexcept;
                void ReadPlayerID(std::uint32_t &) const noexcept;
@@ -108,7 +128,7 @@ struct Packet {
 
        struct PlayerUpdate : public Payload {
                static constexpr std::uint8_t TYPE = 4;
 
        struct PlayerUpdate : public Payload {
                static constexpr std::uint8_t TYPE = 4;
-               static constexpr std::size_t MAX_LEN = 76;
+               static constexpr std::size_t MAX_LEN = 62;
 
                void WritePredictedState(const EntityState &) noexcept;
                void ReadPredictedState(EntityState &) const noexcept;
 
                void WritePredictedState(const EntityState &) noexcept;
                void ReadPredictedState(EntityState &) const noexcept;
@@ -126,11 +146,11 @@ struct Packet {
 
        struct SpawnEntity : public Payload {
                static constexpr std::uint8_t TYPE = 5;
 
        struct SpawnEntity : public Payload {
                static constexpr std::uint8_t TYPE = 5;
-               static constexpr std::size_t MAX_LEN = 132;
+               static constexpr std::size_t MAX_LEN = 118;
 
                void WriteEntity(const Entity &) noexcept;
                void ReadEntityID(std::uint32_t &) const noexcept;
 
                void WriteEntity(const Entity &) noexcept;
                void ReadEntityID(std::uint32_t &) const noexcept;
-               void ReadSkeletonID(std::uint32_t &) const noexcept;
+               void ReadModelID(std::uint32_t &) const noexcept;
                void ReadEntity(Entity &) const noexcept;
        };
 
                void ReadEntity(Entity &) const noexcept;
        };
 
@@ -144,24 +164,26 @@ struct Packet {
 
        struct EntityUpdate : public Payload {
                static constexpr std::uint8_t TYPE = 7;
 
        struct EntityUpdate : public Payload {
                static constexpr std::uint8_t TYPE = 7;
-               static constexpr std::size_t MAX_LEN = 480;
+               static constexpr std::size_t MAX_LEN = 466;
 
 
-               static constexpr std::uint32_t MAX_ENTITIES = 7;
+               static constexpr std::uint32_t MAX_ENTITIES = 10;
                static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
                static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
-                       return 4 + (num * 68);
+                       return 16 + (num * 45);
                }
 
                void WriteEntityCount(std::uint32_t) noexcept;
                void ReadEntityCount(std::uint32_t &) const noexcept;
                }
 
                void WriteEntityCount(std::uint32_t) noexcept;
                void ReadEntityCount(std::uint32_t &) const noexcept;
+               void WriteChunkBase(const glm::ivec3 &) noexcept;
+               void ReadChunkBase(glm::ivec3 &) const noexcept;
 
 
-               void WriteEntity(const Entity &, std::uint32_t) noexcept;
+               void WriteEntity(const Entity &, const glm::ivec3 &, std::uint32_t) noexcept;
                void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
                void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
-               void ReadEntityState(EntityState &, std::uint32_t) const noexcept;
+               void ReadEntityState(EntityState &, const glm::ivec3 &, std::uint32_t) const noexcept;
        };
 
        struct PlayerCorrection : public Payload {
                static constexpr std::uint8_t TYPE = 8;
        };
 
        struct PlayerCorrection : public Payload {
                static constexpr std::uint8_t TYPE = 8;
-               static constexpr std::size_t MAX_LEN = 66;
+               static constexpr std::size_t MAX_LEN = 52;
 
                void WritePacketSeq(std::uint16_t) noexcept;
                void ReadPacketSeq(std::uint16_t &) const noexcept;
 
                void WritePacketSeq(std::uint16_t) noexcept;
                void ReadPacketSeq(std::uint16_t &) const noexcept;
index e267855c301ff24bdf9409640724939e635b22af..86098f4d4a3e087c6b16f03e0546df6f45bfbf59 100644 (file)
@@ -261,6 +261,118 @@ void Packet::Payload::ReadString(string &dst, size_t off, size_t maxlen) const n
        }
 }
 
        }
 }
 
+void Packet::Payload::Write(const glm::quat &val, size_t off) noexcept {
+       WritePackN(val.w, off);
+       WritePackN(val.x, off + 2);
+       WritePackN(val.y, off + 4);
+       WritePackN(val.z, off + 6);
+}
+
+void Packet::Payload::Read(glm::quat &val, size_t off) const noexcept {
+       ReadPackN(val.w, off);
+       ReadPackN(val.x, off + 2);
+       ReadPackN(val.y, off + 4);
+       ReadPackN(val.z, off + 6);
+       val = normalize(val);
+}
+
+void Packet::Payload::Write(const EntityState &state, size_t off) noexcept {
+       Write(state.chunk_pos, off);
+       WritePackU(state.block_pos * (1.0f / 16.0f), off + 12);
+       Write(state.velocity, off + 18);
+       Write(state.orient, off + 30);
+       Write(state.ang_vel, off + 38);
+}
+
+void Packet::Payload::Read(EntityState &state, size_t off) const noexcept {
+       Read(state.chunk_pos, off);
+       ReadPackU(state.block_pos, off + 12);
+       Read(state.velocity, off + 18);
+       Read(state.orient, off + 30);
+       Read(state.ang_vel, off + 38);
+       state.block_pos *= 16.0f;
+}
+
+void Packet::Payload::Write(const EntityState &state, const glm::ivec3 &base, size_t off) noexcept {
+       WritePackB(state.chunk_pos - base, off);
+       WritePackU(state.block_pos * (1.0f / 16.0f), off + 3);
+       Write(state.velocity, off + 9);
+       Write(state.orient, off + 21);
+       Write(state.ang_vel, off + 29);
+}
+
+void Packet::Payload::Read(EntityState &state, const glm::ivec3 &base, size_t off) const noexcept {
+       ReadPackB(state.chunk_pos, off);
+       ReadPackU(state.block_pos, off + 3);
+       Read(state.velocity, off + 9);
+       Read(state.orient, off + 21);
+       Read(state.ang_vel, off + 29);
+       state.chunk_pos += base;
+       state.block_pos *= 16.0f;
+}
+
+void Packet::Payload::WritePackN(float val, size_t off) noexcept {
+       int16_t raw = glm::clamp(glm::round(val * 32767.0f), -32767.0f, 32767.0f);
+       Write(raw, off);
+}
+
+void Packet::Payload::WritePackB(const glm::ivec3 &val, size_t off) noexcept {
+       Write(int8_t(val.x), off);
+       Write(int8_t(val.y), off + 1);
+       Write(int8_t(val.z), off + 2);
+}
+
+void Packet::Payload::ReadPackB(glm::ivec3 &val, size_t off) const noexcept {
+       int8_t conv = 0;
+       Read(conv, off);
+       val.x = conv;
+       Read(conv, off + 1);
+       val.y = conv;
+       Read(conv, off + 2);
+       val.z = conv;
+}
+
+void Packet::Payload::ReadPackN(float &val, size_t off) const noexcept {
+       int16_t raw = 0;
+       Read(raw, off);
+       val = raw * (1.0f/32767.0f);
+}
+
+void Packet::Payload::WritePackN(const glm::vec3 &val, size_t off) noexcept {
+       WritePackN(val.x, off);
+       WritePackN(val.y, off + 2);
+       WritePackN(val.z, off + 4);
+}
+
+void Packet::Payload::ReadPackN(glm::vec3 &val, size_t off) const noexcept {
+       ReadPackN(val.x, off);
+       ReadPackN(val.y, off + 2);
+       ReadPackN(val.z, off + 4);
+}
+
+void Packet::Payload::WritePackU(float val, size_t off) noexcept {
+       uint16_t raw = glm::clamp(glm::round(val * 65535.0f), 0.0f, 65535.0f);
+       Write(raw, off);
+}
+
+void Packet::Payload::ReadPackU(float &val, size_t off) const noexcept {
+       uint16_t raw = 0;
+       Read(raw, off);
+       val = raw * (1.0f/65535.0f);
+}
+
+void Packet::Payload::WritePackU(const glm::vec3 &val, size_t off) noexcept {
+       WritePackU(val.x, off);
+       WritePackU(val.y, off + 2);
+       WritePackU(val.z, off + 4);
+}
+
+void Packet::Payload::ReadPackU(glm::vec3 &val, size_t off) const noexcept {
+       ReadPackU(val.x, off);
+       ReadPackU(val.y, off + 2);
+       ReadPackU(val.z, off + 4);
+}
+
 
 void Packet::Login::WritePlayerName(const string &name) noexcept {
        WriteString(name, 0, 32);
 
 void Packet::Login::WritePlayerName(const string &name) noexcept {
        WriteString(name, 0, 32);
@@ -284,11 +396,11 @@ void Packet::Join::ReadPlayerState(EntityState &state) const noexcept {
 }
 
 void Packet::Join::WriteWorldName(const string &name) noexcept {
 }
 
 void Packet::Join::WriteWorldName(const string &name) noexcept {
-       WriteString(name, 68, 32);
+       WriteString(name, 54, 32);
 }
 
 void Packet::Join::ReadWorldName(string &name) const noexcept {
 }
 
 void Packet::Join::ReadWorldName(string &name) const noexcept {
-       ReadString(name, 68, 32);
+       ReadString(name, 54, 32);
 }
 
 void Packet::PlayerUpdate::WritePredictedState(const EntityState &state) noexcept {
 }
 
 void Packet::PlayerUpdate::WritePredictedState(const EntityState &state) noexcept {
@@ -300,56 +412,47 @@ void Packet::PlayerUpdate::ReadPredictedState(EntityState &state) const noexcept
 }
 
 void Packet::PlayerUpdate::WriteMovement(const glm::vec3 &mov) noexcept {
 }
 
 void Packet::PlayerUpdate::WriteMovement(const glm::vec3 &mov) noexcept {
-       glm::ivec3 conv = clamp(glm::ivec3(mov * 32767.0f), -32767, 32767);
-       Write(int16_t(conv.x), 64);
-       Write(int16_t(conv.y), 66);
-       Write(int16_t(conv.z), 68);
+       WritePackN(mov, 50);
 }
 
 void Packet::PlayerUpdate::ReadMovement(glm::vec3 &mov) const noexcept {
 }
 
 void Packet::PlayerUpdate::ReadMovement(glm::vec3 &mov) const noexcept {
-       int16_t x, y, z;
-       Read(x, 64);
-       Read(y, 66);
-       Read(z, 68);
-       mov = glm::vec3(x, y, z) * .00003051850947599719f;
+       ReadPackN(mov, 50);
 }
 
 void Packet::PlayerUpdate::WritePitch(float pitch) noexcept {
 }
 
 void Packet::PlayerUpdate::WritePitch(float pitch) noexcept {
-       int16_t conv = pitch * 20860.12008116853786870640f;
-       Write(conv, 70);
+       float conv = pitch * PI_0p5_inv;
+       WritePackN(conv, 56);
 }
 
 void Packet::PlayerUpdate::ReadPitch(float &pitch) const noexcept {
 }
 
 void Packet::PlayerUpdate::ReadPitch(float &pitch) const noexcept {
-       int16_t conv = 0;
-       Read(conv, 70);
-       pitch = conv * .00004793836258415163f;
+       ReadPackN(pitch, 56);
+       pitch *= PI_0p5;
 }
 
 void Packet::PlayerUpdate::WriteYaw(float yaw) noexcept {
 }
 
 void Packet::PlayerUpdate::WriteYaw(float yaw) noexcept {
-       int16_t conv = yaw * 10430.06004058426893435320f;
-       Write(conv, 72);
+       float conv = yaw * PI_inv;
+       WritePackN(conv, 58);
 }
 
 void Packet::PlayerUpdate::ReadYaw(float &yaw) const noexcept {
 }
 
 void Packet::PlayerUpdate::ReadYaw(float &yaw) const noexcept {
-       int16_t conv = 0;
-       Read(conv, 72);
-       yaw = conv * .00009587672516830326f;
+       ReadPackN(yaw, 58);
+       yaw *= PI;
 }
 
 void Packet::PlayerUpdate::WriteActions(uint8_t actions) noexcept {
 }
 
 void Packet::PlayerUpdate::WriteActions(uint8_t actions) noexcept {
-       Write(actions, 74);
+       Write(actions, 60);
 }
 
 void Packet::PlayerUpdate::ReadActions(uint8_t &actions) const noexcept {
 }
 
 void Packet::PlayerUpdate::ReadActions(uint8_t &actions) const noexcept {
-       Read(actions, 74);
+       Read(actions, 60);
 }
 
 void Packet::PlayerUpdate::WriteSlot(uint8_t slot) noexcept {
 }
 
 void Packet::PlayerUpdate::WriteSlot(uint8_t slot) noexcept {
-       Write(slot, 75);
+       Write(slot, 61);
 }
 
 void Packet::PlayerUpdate::ReadSlot(uint8_t &slot) const noexcept {
 }
 
 void Packet::PlayerUpdate::ReadSlot(uint8_t &slot) const noexcept {
-       Read(slot, 75);
+       Read(slot, 61);
 }
 
 void Packet::SpawnEntity::WriteEntity(const Entity &e) noexcept {
 }
 
 void Packet::SpawnEntity::WriteEntity(const Entity &e) noexcept {
@@ -360,20 +463,20 @@ void Packet::SpawnEntity::WriteEntity(const Entity &e) noexcept {
                Write(uint32_t(0), 4);
        }
        Write(e.GetState(), 8);
                Write(uint32_t(0), 4);
        }
        Write(e.GetState(), 8);
-       Write(e.Bounds(), 72);
+       Write(e.Bounds(), 58);
        uint32_t flags = 0;
        if (e.WorldCollidable()) {
                flags |= 1;
        }
        uint32_t flags = 0;
        if (e.WorldCollidable()) {
                flags |= 1;
        }
-       Write(flags, 96);
-       WriteString(e.Name(), 100, 32);
+       Write(flags, 82);
+       WriteString(e.Name(), 86, 32);
 }
 
 void Packet::SpawnEntity::ReadEntityID(uint32_t &id) const noexcept {
        Read(id, 0);
 }
 
 }
 
 void Packet::SpawnEntity::ReadEntityID(uint32_t &id) const noexcept {
        Read(id, 0);
 }
 
-void Packet::SpawnEntity::ReadSkeletonID(uint32_t &id) const noexcept {
+void Packet::SpawnEntity::ReadModelID(uint32_t &id) const noexcept {
        Read(id, 4);
 }
 
        Read(id, 4);
 }
 
@@ -384,9 +487,9 @@ void Packet::SpawnEntity::ReadEntity(Entity &e) const noexcept {
        string name;
 
        Read(state, 8);
        string name;
 
        Read(state, 8);
-       Read(bounds, 72);
-       Read(flags, 96);
-       ReadString(name, 100, 32);
+       Read(bounds, 58);
+       Read(flags, 82);
+       ReadString(name, 86, 32);
 
        e.SetState(state);
        e.Bounds(bounds);
 
        e.SetState(state);
        e.Bounds(bounds);
@@ -410,11 +513,19 @@ void Packet::EntityUpdate::ReadEntityCount(uint32_t &count) const noexcept {
        Read(count, 0);
 }
 
        Read(count, 0);
 }
 
-void Packet::EntityUpdate::WriteEntity(const Entity &entity, uint32_t num) noexcept {
+void Packet::EntityUpdate::WriteChunkBase(const glm::ivec3 &base) noexcept {
+       Write(base, 4);
+}
+
+void Packet::EntityUpdate::ReadChunkBase(glm::ivec3 &base) const noexcept {
+       Read(base, 4);
+}
+
+void Packet::EntityUpdate::WriteEntity(const Entity &entity, const glm::ivec3 &base, uint32_t num) noexcept {
        uint32_t off = GetSize(num);
 
        Write(entity.ID(), off);
        uint32_t off = GetSize(num);
 
        Write(entity.ID(), off);
-       Write(entity.GetState(), off + 4);
+       Write(entity.GetState(), base, off + 4);
 }
 
 void Packet::EntityUpdate::ReadEntityID(uint32_t &id, uint32_t num) const noexcept {
 }
 
 void Packet::EntityUpdate::ReadEntityID(uint32_t &id, uint32_t num) const noexcept {
@@ -422,9 +533,9 @@ void Packet::EntityUpdate::ReadEntityID(uint32_t &id, uint32_t num) const noexce
        Read(id, off);
 }
 
        Read(id, off);
 }
 
-void Packet::EntityUpdate::ReadEntityState(EntityState &state, uint32_t num) const noexcept {
+void Packet::EntityUpdate::ReadEntityState(EntityState &state, const glm::ivec3 &base, uint32_t num) const noexcept {
        uint32_t off = GetSize(num);
        uint32_t off = GetSize(num);
-       Read(state, off + 4);
+       Read(state, base, off + 4);
 }
 
 void Packet::PlayerCorrection::WritePacketSeq(std::uint16_t s) noexcept {
 }
 
 void Packet::PlayerCorrection::WritePacketSeq(std::uint16_t s) noexcept {
index e739922b60268062f4c6a708d0de334d03e401cf..b681eec3f74c5d1f3ea576c48d9a2e7138073c7e 100644 (file)
@@ -317,10 +317,12 @@ void ClientConnection::QueueUpdate(SpawnStatus &status) {
 }
 
 void ClientConnection::SendUpdates() {
 }
 
 void ClientConnection::SendUpdates() {
+       auto base = PlayerChunks().Base();
        auto pack = Prepare<Packet::EntityUpdate>();
        auto pack = Prepare<Packet::EntityUpdate>();
+       pack.WriteChunkBase(base);
        int entity_pos = 0;
        for (SpawnStatus *status : entity_updates) {
        int entity_pos = 0;
        for (SpawnStatus *status : entity_updates) {
-               pack.WriteEntity(*status->entity, entity_pos);
+               pack.WriteEntity(*status->entity, base, entity_pos);
                ++entity_pos;
                if (entity_pos == Packet::EntityUpdate::MAX_ENTITIES) {
                        pack.WriteEntityCount(entity_pos);
                ++entity_pos;
                if (entity_pos == Packet::EntityUpdate::MAX_ENTITIES) {
                        pack.WriteEntityCount(entity_pos);
index 5b6deed47974c1285f679d824d227ab603a0bc3d..6803110ca969092d3e1b1c890bfb6f00d6283ef3 100644 (file)
@@ -34,14 +34,6 @@ void PacketTest::testSizes() {
                "unexpected size of vec3i",
                size_t(12), sizeof(glm::ivec3)
        );
                "unexpected size of vec3i",
                size_t(12), sizeof(glm::ivec3)
        );
-       CPPUNIT_ASSERT_EQUAL_MESSAGE(
-               "unexpected size of quat",
-               size_t(16), sizeof(glm::quat)
-       );
-       CPPUNIT_ASSERT_EQUAL_MESSAGE(
-               "unexpected size of entity state",
-               size_t(64), sizeof(EntityState)
-       );
 }
 
 void PacketTest::testControl() {
 }
 
 void PacketTest::testControl() {
@@ -116,7 +108,7 @@ void PacketTest::testLogin() {
 
 void PacketTest::testJoin() {
        auto pack = Packet::Make<Packet::Join>(udp_pack);
 
 void PacketTest::testJoin() {
        auto pack = Packet::Make<Packet::Join>(udp_pack);
-       AssertPacket("Join", 2, 68, 100, pack);
+       AssertPacket("Join", 2, 54, 86, pack);
 
        Entity write_entity;
        write_entity.ID(534574);
 
        Entity write_entity;
        write_entity.ID(534574);
@@ -165,7 +157,7 @@ void PacketTest::testPart() {
 
 void PacketTest::testPlayerUpdate() {
        auto pack = Packet::Make<Packet::PlayerUpdate>(udp_pack);
 
 void PacketTest::testPlayerUpdate() {
        auto pack = Packet::Make<Packet::PlayerUpdate>(udp_pack);
-       AssertPacket("PlayerUpdate", 4, 76, pack);
+       AssertPacket("PlayerUpdate", 4, 62, pack);
 
        EntityState write_state;
        write_state.chunk_pos = { 7, 2, -3 };
 
        EntityState write_state;
        write_state.chunk_pos = { 7, 2, -3 };
@@ -225,7 +217,7 @@ void PacketTest::testPlayerUpdate() {
 
 void PacketTest::testSpawnEntity() {
        auto pack = Packet::Make<Packet::SpawnEntity>(udp_pack);
 
 void PacketTest::testSpawnEntity() {
        auto pack = Packet::Make<Packet::SpawnEntity>(udp_pack);
-       AssertPacket("SpawnEntity", 5, 100, 132, pack);
+       AssertPacket("SpawnEntity", 5, 87, 118, pack);
 
        Entity write_entity;
        write_entity.ID(534574);
 
        Entity write_entity;
        write_entity.ID(534574);
@@ -243,10 +235,10 @@ void PacketTest::testSpawnEntity() {
        pack.WriteEntity(write_entity);
 
        uint32_t entity_id;
        pack.WriteEntity(write_entity);
 
        uint32_t entity_id;
-       uint32_t skeleton_id;
+       uint32_t model_id;
        Entity read_entity;
        pack.ReadEntityID(entity_id);
        Entity read_entity;
        pack.ReadEntityID(entity_id);
-       pack.ReadSkeletonID(skeleton_id);
+       pack.ReadModelID(model_id);
        pack.ReadEntity(read_entity);
 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
        pack.ReadEntity(read_entity);
 
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
@@ -254,8 +246,8 @@ void PacketTest::testSpawnEntity() {
                write_entity.ID(), entity_id
        );
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                write_entity.ID(), entity_id
        );
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
-               "skeleton ID not correctly transported in SpawnEntity packet",
-               write_entity.GetModel().GetModel().ID(), skeleton_id
+               "model ID not correctly transported in SpawnEntity packet",
+               write_entity.GetModel().GetModel().ID(), model_id
        );
        AssertEqual(
                "entity state not correctly transported in PlayerUpdate packet",
        );
        AssertEqual(
                "entity state not correctly transported in PlayerUpdate packet",
@@ -292,22 +284,32 @@ void PacketTest::testDespawnEntity() {
 
 void PacketTest::testEntityUpdate() {
        auto pack = Packet::Make<Packet::EntityUpdate>(udp_pack);
 
 void PacketTest::testEntityUpdate() {
        auto pack = Packet::Make<Packet::EntityUpdate>(udp_pack);
-       AssertPacket("EntityUpdate", 7, 4, 480, pack);
+       AssertPacket("EntityUpdate", 7, 16, 466, pack);
 
        pack.length = Packet::EntityUpdate::GetSize(3);
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "length not correctly set in EntityUpdate packet",
 
        pack.length = Packet::EntityUpdate::GetSize(3);
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "length not correctly set in EntityUpdate packet",
-               size_t(4 + 3 * 68), pack.length
+               size_t(16 + 3 * 45), pack.length
        );
 
        uint32_t write_count = 3;
        );
 
        uint32_t write_count = 3;
-       uint32_t read_count;
+       glm::ivec3 write_base(8, -15, 1);
        pack.WriteEntityCount(write_count);
        pack.WriteEntityCount(write_count);
+       pack.WriteChunkBase(write_base);
+
+       uint32_t read_count;
+       glm::ivec3 read_base;
        pack.ReadEntityCount(read_count);
        pack.ReadEntityCount(read_count);
+       pack.ReadChunkBase(read_base);
+
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "entity count not correctly transported in EntityUpdate packet",
                write_count, read_count
        );
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "entity count not correctly transported in EntityUpdate packet",
                write_count, read_count
        );
+       AssertEqual(
+               "chunk base not correctly transported in EntityUpdate packet",
+               write_base, read_base
+       );
 
        Entity write_entity;
        write_entity.ID(8567234);
 
        Entity write_entity;
        write_entity.ID(8567234);
@@ -316,14 +318,14 @@ void PacketTest::testEntityUpdate() {
        write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
        write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
        write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
        write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
        write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
        write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
-       pack.WriteEntity(write_entity, 1);
-       pack.WriteEntity(write_entity, 0);
-       pack.WriteEntity(write_entity, 2);
+       pack.WriteEntity(write_entity, write_base, 1);
+       pack.WriteEntity(write_entity, write_base, 0);
+       pack.WriteEntity(write_entity, write_base, 2);
 
        uint32_t read_id;
        EntityState read_state;
        pack.ReadEntityID(read_id, 1);
 
        uint32_t read_id;
        EntityState read_state;
        pack.ReadEntityID(read_id, 1);
-       pack.ReadEntityState(read_state, 1);
+       pack.ReadEntityState(read_state, write_base, 1);
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "entity ID not correctly transported in EntityUpdate packet",
                write_entity.ID(), read_id
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
                "entity ID not correctly transported in EntityUpdate packet",
                write_entity.ID(), read_id
@@ -336,7 +338,7 @@ void PacketTest::testEntityUpdate() {
 
 void PacketTest::testPlayerCorrection() {
        auto pack = Packet::Make<Packet::PlayerCorrection>(udp_pack);
 
 void PacketTest::testPlayerCorrection() {
        auto pack = Packet::Make<Packet::PlayerCorrection>(udp_pack);
-       AssertPacket("PlayerCorrection", 8, 66, pack);
+       AssertPacket("PlayerCorrection", 8, 52, pack);
 
        uint16_t write_seq = 50050;
        uint16_t read_seq;
 
        uint16_t write_seq = 50050;
        uint16_t read_seq;
@@ -603,7 +605,7 @@ void PacketTest::AssertEqual(
        );
        AssertEqual(
                message + ": bad block position",
        );
        AssertEqual(
                message + ": bad block position",
-               expected.block_pos, actual.block_pos
+               expected.block_pos, actual.block_pos, 16.0f/65535.0f // that's about the max accuracy that packing's going to give us
        );
        AssertEqual(
                message + ": bad velocity",
        );
        AssertEqual(
                message + ": bad velocity",