mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 00:20:54 +01:00
103 lines
3.1 KiB
C++
103 lines
3.1 KiB
C++
#include <TiltedOnlinePCH.h>
|
|
|
|
#include <Systems/InterpolationSystem.h>
|
|
#include <Components.h>
|
|
|
|
#include <AI/AIProcess.h>
|
|
#include <Misc/MiddleProcess.h>
|
|
|
|
#include <Games/References.h>
|
|
#include <World.h>
|
|
|
|
void InterpolationSystem::Update(Actor* apActor, InterpolationComponent& aInterpolationComponent, const uint64_t aTick) noexcept
|
|
{
|
|
auto& movements = aInterpolationComponent.TimePoints;
|
|
|
|
if (movements.size() < 2)
|
|
return;
|
|
|
|
while (movements.size() > 2)
|
|
{
|
|
const auto second = *(++movements.begin());
|
|
if (aTick > second.Tick)
|
|
movements.pop_front();
|
|
else
|
|
break;
|
|
}
|
|
|
|
const auto& first = *(movements.begin());
|
|
const auto& second = *(++movements.begin());
|
|
|
|
// Calculate delta movement since last update
|
|
auto delta = 0.0001f;
|
|
const auto tickDelta = static_cast<float>(second.Tick - first.Tick);
|
|
if (tickDelta > 0.f)
|
|
{
|
|
delta = 1.f / tickDelta * static_cast<float>(aTick - first.Tick);
|
|
}
|
|
|
|
delta = TiltedPhoques::Min(delta, 1.0f);
|
|
|
|
const NiPoint3 position{TiltedPhoques::Lerp(first.Position, second.Position, delta)};
|
|
|
|
aInterpolationComponent.Position = position;
|
|
|
|
// Don't try to move a null actor
|
|
if (!apActor)
|
|
return;
|
|
|
|
apActor->ForcePosition(position);
|
|
apActor->LoadAnimationVariables(second.Variables);
|
|
|
|
if (apActor->currentProcess && apActor->currentProcess->middleProcess)
|
|
{
|
|
apActor->currentProcess->middleProcess->direction = second.Direction;
|
|
}
|
|
|
|
auto rotA = first.Rotation;
|
|
auto rotB = second.Rotation;
|
|
|
|
const auto deltaX = TiltedPhoques::DeltaAngle(rotA.x, rotB.x, true) * delta;
|
|
const auto deltaY = TiltedPhoques::DeltaAngle(rotA.y, rotB.y, true) * delta;
|
|
const auto deltaZ = TiltedPhoques::DeltaAngle(rotA.z, rotB.z, true) * delta;
|
|
|
|
auto finalX = TiltedPhoques::Mod(rotA.x + deltaX, float(TiltedPhoques::Pi * 2));
|
|
if (finalX > 0.f && finalX > float(TiltedPhoques::Pi / 2))
|
|
finalX -= TiltedPhoques::Pi * 2;
|
|
|
|
const auto finalY = TiltedPhoques::Mod(rotA.y + deltaY, float(TiltedPhoques::Pi * 2));
|
|
const auto finalZ = TiltedPhoques::Mod(rotA.z + deltaZ, float(TiltedPhoques::Pi * 2));
|
|
|
|
apActor->SetRotation(finalX, finalY, finalZ);
|
|
}
|
|
|
|
void InterpolationSystem::AddPoint(InterpolationComponent& aInterpolationComponent, const InterpolationComponent::TimePoint& acPoint) noexcept
|
|
{
|
|
auto itor = std::begin(aInterpolationComponent.TimePoints);
|
|
const auto end = std::cend(aInterpolationComponent.TimePoints);
|
|
|
|
while (itor != end)
|
|
{
|
|
if (itor->Tick > acPoint.Tick)
|
|
{
|
|
aInterpolationComponent.TimePoints.insert(itor, acPoint);
|
|
|
|
return;
|
|
}
|
|
|
|
++itor;
|
|
}
|
|
|
|
aInterpolationComponent.TimePoints.push_back(acPoint);
|
|
}
|
|
|
|
InterpolationComponent& InterpolationSystem::Setup(World& aWorld, const entt::entity aEntity) noexcept
|
|
{
|
|
return aWorld.emplace_or_replace<InterpolationComponent>(aEntity);
|
|
}
|
|
|
|
void InterpolationSystem::Clean(World& aWorld, const entt::entity aEntity) noexcept
|
|
{
|
|
if (aWorld.all_of<InterpolationComponent>(aEntity))
|
|
aWorld.remove<InterpolationComponent>(aEntity);
|
|
}
|