Skip to content

Commit 49c4b2e

Browse files
committed
feat: add experimental camera smoothing in raw tas
1 parent 68d5667 commit 49c4b2e

4 files changed

Lines changed: 73 additions & 14 deletions

File tree

src/Features/Tas/TasController.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,11 @@ std::chrono::time_point<std::chrono::high_resolution_clock> g_lastControllerMove
112112
void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd) {
113113
// ControllerMove is executed several times for one tick. Most of them
114114
// are called from ExtraMouseSamples with 0 tick count. We want to filter them out.
115-
if (cmd->tick_count == 0) return;
115+
bool wasInExtraMouseSamples = inExtraMouseSamples;
116+
inExtraMouseSamples = cmd->tick_count == 0;
116117

117118
// doing some debugs to test the behaviour of the real controller
118-
if (sar_tas_real_controller_debug.GetBool()) {
119+
if (sar_tas_real_controller_debug.GetBool() && !inExtraMouseSamples) {
119120
int debugType = sar_tas_real_controller_debug.GetInt();
120121
if (debugType == 1) {
121122
console->Print("forwardmove: %.5f, sidemove: %.5f\n", cmd->forwardmove, cmd->sidemove);
@@ -140,6 +141,23 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
140141

141142
//console->Print("TasController::ControllerMove (%d, ", cmd->tick_count);
142143

144+
if (inExtraMouseSamples && !tasPlayer->IsUsingTools()) {
145+
if (!wasInExtraMouseSamples) {
146+
viewanglesPreExtraMouseSamples = engine->GetAngles(nSlot);
147+
}
148+
149+
extraMouseSamplesAccumulatedTime += flFrametime;
150+
151+
auto extraViewAnalog = tasPlayer->FetchRawExtraViewAnalog(nSlot, extraMouseSamplesAccumulatedTime);
152+
ApplyViewAnalog(nSlot, nullptr, extraViewAnalog, true);
153+
154+
return;
155+
}
156+
157+
if (wasInExtraMouseSamples) {
158+
extraMouseSamplesAccumulatedTime = 0.0f;
159+
}
160+
143161
tasPlayer->FetchInputs(nSlot, this, cmd);
144162

145163
//TAS is now controlling inputs. Reset everything we can.
@@ -197,17 +215,7 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
197215
// don't do this part if tools are enabled.
198216
// tools processing will do it instead
199217
if (!tasPlayer->IsUsingTools()) {
200-
QAngle viewangles;
201-
viewangles = engine->GetAngles(nSlot);
202-
203-
viewangles.y -= viewAnalog.x; // positive values should rotate right.
204-
viewangles.x -= viewAnalog.y; // positive values should rotate up.
205-
viewangles.x = std::min(std::max(viewangles.x, -cl_pitchdown.GetFloat()), cl_pitchup.GetFloat());
206-
207-
cmd->mousedx = (int)(-viewAnalog.x);
208-
cmd->mousedy = (int)(-viewAnalog.y);
209-
210-
engine->SetAngles(nSlot, viewangles);
218+
ApplyViewAnalog(nSlot, cmd, viewAnalog, wasInExtraMouseSamples);
211219
}
212220

213221
{
@@ -219,3 +227,23 @@ void TasController::ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd)
219227
tasPlayer->DumpUsercmd(nSlot, &tmp, tasPlayer->GetTick() + 1, "client"); // off-by-one bullshit on tick count
220228
}
221229
}
230+
231+
void TasController::ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog, bool usePreExtraMouseSampleAngles) {
232+
QAngle viewangles;
233+
viewangles = engine->GetAngles(nSlot);
234+
235+
if (usePreExtraMouseSampleAngles) {
236+
viewangles = viewanglesPreExtraMouseSamples;
237+
}
238+
239+
viewangles.y -= analog.x; // positive values should rotate right.
240+
viewangles.x -= analog.y; // positive values should rotate up.
241+
viewangles.x = std::min(std::max(viewangles.x, -cl_pitchdown.GetFloat()), cl_pitchup.GetFloat());
242+
243+
if (cmd != nullptr) {
244+
cmd->mousedx = (int)(-analog.x);
245+
cmd->mousedy = (int)(-analog.y);
246+
}
247+
248+
engine->SetAngles(nSlot, viewangles);
249+
}

src/Features/Tas/TasController.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class TasController : public Feature {
3838

3939
bool enabled;
4040

41+
bool inExtraMouseSamples;
42+
float extraMouseSamplesAccumulatedTime;
43+
QAngle viewanglesPreExtraMouseSamples;
44+
4145
public:
4246
TasController();
4347
~TasController();
@@ -60,6 +64,9 @@ class TasController : public Feature {
6064
void SetButtonState(TasControllerInput i, bool state);
6165

6266
void ControllerMove(int nSlot, float flFrametime, CUserCmd *cmd);
67+
68+
private:
69+
void ApplyViewAnalog(int nSlot, CUserCmd *cmd, Vector analog, bool usePreExtraMouseSampleAngles);
6370
};
6471

6572
extern TasController *tasControllers[2];

src/Features/Tas/TasPlayer.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void TasPlayer::Activate(TasPlaybackInfo info) {
168168
playbackInfo.slots[slot].ClearGeneratedContent();
169169

170170
currentRequestRawFramebulkIndex[slot] = 0;
171-
171+
currentExtraViewAnalogRawFramebulkIndex[slot] = 0;
172172
}
173173

174174
active = true;
@@ -565,6 +565,28 @@ void TasPlayer::SaveProcessedFramebulks() {
565565
}
566566
}
567567

568+
// Used by controller for ExtraMouseSample's. Not necessary for gameplay inputs but makes raw playback smooth
569+
Vector TasPlayer::FetchRawExtraViewAnalog(int slot, float frametime) {
570+
571+
int tasTick = currentTick + 1;
572+
float frametimeInTicks = frametime / engine->GetIPT();
573+
int lastSampleTick = ceilf(tasTick + frametimeInTicks);
574+
575+
GetRawFramebulkAt(slot, tasTick, currentExtraViewAnalogRawFramebulkIndex[slot]);
576+
unsigned framebulkIndex = currentExtraViewAnalogRawFramebulkIndex[slot];
577+
578+
Vector accumulatedAnalog = Vector();
579+
580+
float remainingFrametimeInTicks = frametimeInTicks;
581+
for (int tick = tasTick; tick <= lastSampleTick; tick++) {
582+
TasFramebulk fb = GetRawFramebulkAt(slot, tick, framebulkIndex);
583+
accumulatedAnalog += fb.viewAnalog * fminf(1.0f, remainingFrametimeInTicks);
584+
remainingFrametimeInTicks -= 1.0f;
585+
}
586+
587+
return accumulatedAnalog;
588+
}
589+
568590
/*
569591
This function is called by TAS controller's ControllerMove function.
570592
Even with alternateticks, the shortest interval between two ticks

src/Features/Tas/TasPlayer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class TasPlayer : public Feature {
7676

7777
// used to cache last used framebulk to quickly access it for playback
7878
unsigned currentRequestRawFramebulkIndex[2];
79+
unsigned currentExtraViewAnalogRawFramebulkIndex[2];
7980

8081
public:
8182
void Update();
@@ -118,6 +119,7 @@ class TasPlayer : public Feature {
118119
void SaveUsercmdDebugs(int slot);
119120
void SavePlayerInfoDebugs(int slot);
120121

122+
Vector FetchRawExtraViewAnalog(int slot, float frametime);
121123
void FetchInputs(int slot, TasController *controller, CUserCmd *cmd);
122124
TasFramebulk SamplePreProcessedFramebulk(int slot, int tasTick, void *player, CUserCmd *cmd);
123125
void PostProcess(int slot, void *player, CUserCmd *cmd);

0 commit comments

Comments
 (0)