From d7780d8248eb696b44fc7b9ca43cab55cb0dff38 Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 18 Jan 2016 17:11:37 +0100 Subject: [PATCH] WIP implementing interpolation --- include/Engine/Network/EInterpolate.h | 20 +++++++++++ include/Game/InterpolationSystem.h | 42 ++++++++++++++++++++++ src/Game/InterpolationSystem.cpp | 50 +++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 include/Engine/Network/EInterpolate.h create mode 100644 include/Game/InterpolationSystem.h create mode 100644 src/Game/InterpolationSystem.cpp diff --git a/include/Engine/Network/EInterpolate.h b/include/Engine/Network/EInterpolate.h new file mode 100644 index 00000000..65038e49 --- /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/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; +}