diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 6aaa9e77..73f0eb50 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -19,6 +19,7 @@ #include "Core/ConfigFile.h" #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" +#include "Network/EInterpolate.h" class Client : public Network { diff --git a/include/Engine/Network/EInterpolate.h b/include/Engine/Network/EInterpolate.h new file mode 100644 index 00000000..93bf1a5c --- /dev/null +++ b/include/Engine/Network/EInterpolate.h @@ -0,0 +1,20 @@ +#ifndef Events_Interpolate_h__ +#define Events_Interpolate_h__ + +#include + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct Interpolate : Event +{ + EntityID Entity; + boost::shared_array DataArray; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/InterpolationSystem.h b/include/Game/InterpolationSystem.h new file mode 100644 index 00000000..c87ee5a7 --- /dev/null +++ b/include/Game/InterpolationSystem.h @@ -0,0 +1,42 @@ +#ifndef Systems_InterpolationSystem_h__ +#define Systems_InterpolationSystem_h__ + +#include +#include +#include +#include + +#include "Common.h" +#include "Core/System.h" +#include "Core/EventBroker.h" + +#include "Network/EInterpolate.h" + +struct Transform { + glm::vec3 Position; + glm::vec3 Scale; + glm::vec3 Orientation; + double interpolationTime; +}; + +class InterpolationSystem : public PureSystem +{ +public: + InterpolationSystem(EventBroker* eventbroker) + : PureSystem(eventbroker, "Transform") + { + EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); + } + ~InterpolationSystem() { } + + virtual void UpdateComponent(World* world, ComponentWrapper& transform, double dt) override; +private: + std::unordered_map> m_InterpolationPoints; + + glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime); + + EventRelay m_EInterpolate; + bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); +}; + +#endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 9ffd570b..38eaf235 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -118,12 +118,16 @@ void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInf int sizeOfFields = 0; for (auto field : componentInfo.FieldsInOrder) { ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); - sizeOfFields = fieldInfo.Stride; + sizeOfFields += fieldInfo.Stride; } // Is the size correct? boost::shared_array eventData(new char[componentInfo.Meta.Stride]); memcpy(eventData.get(), packet.ReadData(componentInfo.Meta.Stride), componentInfo.Meta.Stride); //Send event to interpolat system + Events::Interpolate e; + e.Entity = entityID; + e.DataArray = eventData; + m_EventBroker->Publish(e); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 422d6523..9ec1a041 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -27,6 +27,7 @@ void Server::Update() m_EventBroker->Process(); } + void Server::readFromClients() { while (m_Socket.available()) { diff --git a/src/Game/InterpolationSystem.cpp b/src/Game/InterpolationSystem.cpp new file mode 100644 index 00000000..d2d81fda --- /dev/null +++ b/src/Game/InterpolationSystem.cpp @@ -0,0 +1,50 @@ +#include "InterpolationSystem.h" + +void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt) +{ + if (m_InterpolationPoints[transform.EntityID].size() > 0) { + Transform& sTransform = m_InterpolationPoints[transform.EntityID].front(); + sTransform.interpolationTime += dt; + if (sTransform.interpolationTime > 0.05) { + double time = std::fmod(sTransform.interpolationTime, 0.05f); + m_InterpolationPoints[transform.EntityID].pop(); + if (m_InterpolationPoints[transform.EntityID].size() <= 0) { + return; + } + sTransform = m_InterpolationPoints[transform.EntityID].front(); + sTransform.interpolationTime = time; + } + glm::vec3 nextPosition = sTransform.Position; + glm::vec3 currentPosition = static_cast(transform["Position"]); + transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); + } +} + +glm::vec3 InterpolationSystem::vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime) +{ + glm::vec3 difference = next - prev; + glm::vec3 position = difference / 0.05f * static_cast(currentTime); + return position; +} + +bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) +{ + Transform transform; + int offset = 0; + // Read the data + memcpy(&transform.Position, e.DataArray.get() + offset, sizeof(glm::vec3)); + offset += sizeof(glm::vec3); + memcpy(&transform.Orientation, e.DataArray.get() + offset, sizeof(glm::vec3)); + offset += sizeof(glm::vec3); + memcpy(&transform.Scale, e.DataArray.get() + offset, sizeof(glm::vec3)); + + // Check if queue already exists + if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue + m_InterpolationPoints[e.Entity].push(transform); + } else { // Did not exist, create queue + std::queue transformQueue; + transformQueue.push(transform); + m_InterpolationPoints[e.Entity] = transformQueue; + } + return false; +}