Skip to content
This repository has been archived by the owner on Oct 10, 2024. It is now read-only.

Commit

Permalink
polyline simplification
Browse files Browse the repository at this point in the history
  • Loading branch information
kotae4 committed Feb 13, 2022
1 parent 78ef4da commit 39a7a43
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 9 deletions.
39 changes: 35 additions & 4 deletions gui/replay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "gui-helpers.hpp"
#include <sstream>
#include "profiler.h"
#include "logger.h"

namespace Replay
{
Expand Down Expand Up @@ -297,16 +298,46 @@ namespace Replay
}
Profiler::EndSample("ReplayLoop");

Profiler::BeginSample("ReplayPolyline");
for (int plrIdx = 0; plrIdx < State.replayWalkPolylineByPlayer.size(); plrIdx++)
{
Replay::WalkEvent_LineData plrLineData = State.replayWalkPolylineByPlayer.at(plrIdx);
for (auto& point : plrLineData.points)

// CREDIT:
// https://github.com/mourner/simplify-js/blob/master/simplify.js#L51
// https://github.com/mourner/simplify-js/blob/master/LICENSE
ImVec2 prevPoint = plrLineData.pendingPoints[0], point = {0.f, 0.f};
size_t numPendingPoints = plrLineData.pendingPoints.size();
size_t numNewPointsAdded = 1;
// always add the first point
plrLineData.simplifiedPoints.push_back(ImVec2(prevPoint.x + cursorPosX, prevPoint.y + cursorPosY));
for (size_t index = 1; index < numPendingPoints; index++)
{
point.x += cursorPosX;
point.y += cursorPosY;
point = plrLineData.pendingPoints[index];
float diffX = point.x - prevPoint.x, diffY = point.y - prevPoint.y;
if ((diffX * diffX + diffY * diffY) > 1.5f)
{
prevPoint = point;
point.x += cursorPosX;
point.y += cursorPosY;
// add the point if it's beyond 1.5 units squared of prev point.
plrLineData.simplifiedPoints.push_back(point);
numNewPointsAdded++;
}
}
drawList->AddPolyline(plrLineData.points.data(), plrLineData.points.size(), GetReplayPlayerColor(plrLineData.colorId), false, 1.f);
// add the last point if it's not also the first point
if ((point.x != prevPoint.x) && (point.y != prevPoint.y))
{
plrLineData.simplifiedPoints.push_back(ImVec2(point.x + cursorPosX, point.y + cursorPosY));
numNewPointsAdded++;
}

plrLineData.pendingPoints.clear();
//STREAM_DEBUG("Using " << numNewPointsAdded << " points out of " << numPendingPoints);

drawList->AddPolyline(plrLineData.simplifiedPoints.data(), plrLineData.simplifiedPoints.size(), GetReplayPlayerColor(plrLineData.colorId), false, 1.f);
}
Profiler::EndSample("ReplayPolyline");


ImGui::EndChild();
Expand Down
3 changes: 2 additions & 1 deletion gui/replay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Replay
struct WalkEvent_LineData
{
uint8_t colorId;
std::vector<ImVec2> points;
std::vector<ImVec2> pendingPoints;
std::vector<ImVec2> simplifiedPoints;
};
}
4 changes: 4 additions & 0 deletions gui/tabs/debug_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace DebugTab {

ImGui::Dummy(ImVec2(4, 4));

ImGui::Text("Num Events: %d", State.events.size());

if (ImGui::CollapsingHeader("Profiler"))
{
if (ImGui::Button("Clear Stats"))
Expand All @@ -49,8 +51,10 @@ namespace DebugTab {

std::stringstream statStream;
//Profiler::AppendStatStringStream("ClearEvents", statStream);
Profiler::AppendStatStringStream("WalkEventCreation", statStream);
Profiler::AppendStatStringStream("ReplayRender", statStream);
Profiler::AppendStatStringStream("ReplayLoop", statStream);
Profiler::AppendStatStringStream("ReplayPolyline", statStream);
//Profiler::AppendStatStringStream("ReplayFilter", statStream);
//Profiler::AppendStatStringStream("ReplayCoreLoopIter", statStream);
Profiler::AppendStatStringStream("ReplayKillEvent", statStream);
Expand Down
11 changes: 7 additions & 4 deletions hooks/PlayerControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "esp.hpp"
#include "_rpc.h"
#include "replay.hpp"
#include "profiler.h"
#include <iostream>
#include <optional>

Expand Down Expand Up @@ -152,24 +153,26 @@ void dPlayerControl_FixedUpdate(PlayerControl* __this, MethodInfo* method) {
State.lastWalkEventPosPerPlayer[__this->fields.PlayerId].x = playerPos.x;
State.lastWalkEventPosPerPlayer[__this->fields.PlayerId].y = playerPos.y;

std::lock_guard<std::mutex> replayLock(Replay::replayEventMutex);
if (!State.InMeeting)
{
Profiler::BeginSample("WalkEventCreation");
std::lock_guard<std::mutex> replayLock(Replay::replayEventMutex);
float dist = GetDistanceBetweenPoints_Unity(playerPos, prevPlayerPos);
if (dist > 0.f)
{
State.events.emplace_back(std::make_unique<WalkEvent>(GetEventPlayerControl(__this).value(), playerPos));
ImVec2 lineData = {maps[State.mapType].x_offset + (playerPos.x * maps[State.mapType].scale), maps[State.mapType].y_offset - (playerPos.y * maps[State.mapType].scale)};
ImVec2 mapPos_pre = {maps[State.mapType].x_offset + (playerPos.x * maps[State.mapType].scale), maps[State.mapType].y_offset - (playerPos.y * maps[State.mapType].scale)};
if (State.replayWalkPolylineByPlayer.find(__this->fields.PlayerId) == State.replayWalkPolylineByPlayer.end())
{
// initialize its value
State.replayWalkPolylineByPlayer[__this->fields.PlayerId] = {};
State.replayWalkPolylineByPlayer[__this->fields.PlayerId].points = {};
State.replayWalkPolylineByPlayer[__this->fields.PlayerId].pendingPoints = {};
// bad. but not worried about micro-optimizations right now.
State.replayWalkPolylineByPlayer[__this->fields.PlayerId].colorId = GetEventPlayerControl(__this).value().colorId;
}
State.replayWalkPolylineByPlayer[__this->fields.PlayerId].points.push_back(lineData);
State.replayWalkPolylineByPlayer[__this->fields.PlayerId].pendingPoints.push_back(mapPos_pre);
}
Profiler::EndSample("WalkEventCreation");
}

PlayerData espPlayerData;
Expand Down

0 comments on commit 39a7a43

Please sign in to comment.