From 50b20fb1cd680f204fe1612de37526e719880c8e Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Sun, 4 Oct 2020 02:30:36 +0200 Subject: [PATCH] Make animations more consistent with high float values --- src/game/client/components/maplayers.cpp | 54 +++++++++++++++--------- src/game/client/components/maplayers.h | 2 +- src/game/client/components/mapsounds.cpp | 4 +- src/game/client/render.h | 4 +- src/game/client/render_map.cpp | 19 +++++---- src/game/editor/editor.cpp | 4 +- src/game/editor/editor.h | 4 +- src/game/editor/layer_sounds.cpp | 4 +- 8 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index a045963c6..61b453086 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -59,7 +59,7 @@ void CMapLayers::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *p Graphics()->MapScreen(Points[0], Points[1], Points[2], Points[3]); } -void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) +void CMapLayers::EnvelopeEval(int TimeOffsetMillis, int Env, float *pChannels, void *pUser) { CMapLayers *pThis = (CMapLayers *)pUser; pChannels[0] = 0; @@ -84,8 +84,10 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void CMapItemEnvelope *pItem = (CMapItemEnvelope *)pThis->m_pLayers->Map()->GetItem(Start + Env, 0, 0); - static float s_Time = 0.0f; - static float s_LastLocalTime = pThis->LocalTime(); + const int64 TickToMicroSeconds = (1000000ll / (int64)pThis->Client()->GameTickSpeed()); + + static int64 s_Time = 0; + static int64 s_LastLocalTime = time_get_microseconds(); if(pThis->Client()->State() == IClient::STATE_DEMOPLAYBACK) { const IDemoPlayer::CInfo *pInfo = pThis->DemoPlayer()->BaseInfo(); @@ -99,18 +101,26 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void } if(pItem->m_Version < 2 || pItem->m_Synchronized) { - s_Time = mix((pThis->Client()->PrevGameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), - (pThis->Client()->GameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), - pThis->Client()->IntraGameTick(g_Config.m_ClDummy)); + // get the lerp of the current tick and prev + int MinTick = pThis->Client()->PrevGameTick(g_Config.m_ClDummy); + s_Time = (int64)(mix( + 0, + (pThis->Client()->GameTick(g_Config.m_ClDummy) - MinTick), + pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) * + TickToMicroSeconds) + + MinTick * TickToMicroSeconds; } else { - s_Time = mix(pThis->m_LastLocalTick / (float)pThis->Client()->GameTickSpeed(), - pThis->m_CurrentLocalTick / (float)pThis->Client()->GameTickSpeed(), - pThis->Client()->IntraGameTick(g_Config.m_ClDummy)); + int MinTick = pThis->m_LastLocalTick; + s_Time = (int64)(mix(0, + pThis->m_CurrentLocalTick - MinTick, + pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) * + TickToMicroSeconds) + + MinTick * TickToMicroSeconds; } } - pThis->RenderTools()->RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + TimeOffset, pChannels); + pThis->RenderTools()->RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + (int64)TimeOffsetMillis * 1000ll, pChannels); } else { @@ -118,17 +128,23 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void { if(pThis->m_pClient->m_Snap.m_pGameInfoObj) // && !(pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) { - s_Time = mix((pThis->Client()->PrevGameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), - (pThis->Client()->GameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), - pThis->Client()->IntraGameTick(g_Config.m_ClDummy)); + // get the lerp of the current tick and prev + int MinTick = pThis->Client()->PrevGameTick(g_Config.m_ClDummy); + s_Time = (int64)(mix( + 0, + (pThis->Client()->GameTick(g_Config.m_ClDummy) - MinTick), + pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) * + TickToMicroSeconds) + + MinTick * TickToMicroSeconds; } } else { - s_Time += pThis->LocalTime() - s_LastLocalTime; - s_LastLocalTime = pThis->LocalTime(); + int64 CurTime = time_get_microseconds(); + s_Time += CurTime - s_LastLocalTime; + s_LastLocalTime = CurTime; } - pThis->RenderTools()->RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + TimeOffset, pChannels); + pThis->RenderTools()->RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + (int64)TimeOffsetMillis * 1000ll, pChannels); } } @@ -989,7 +1005,7 @@ void CMapLayers::RenderTileLayer(int LayerIndex, ColorRGBA *pColor, CMapItemLaye if(pTileLayer->m_ColorEnv >= 0) { float aChannels[4]; - EnvelopeEval(pTileLayer->m_ColorEnvOffset / 1000.0f, pTileLayer->m_ColorEnv, aChannels, this); + EnvelopeEval(pTileLayer->m_ColorEnvOffset, pTileLayer->m_ColorEnv, aChannels, this); r = aChannels[0]; g = aChannels[1]; b = aChannels[2]; @@ -1379,7 +1395,7 @@ void CMapLayers::RenderQuadLayer(int LayerIndex, CMapItemLayerQuads *pQuadLayer, aColor[0] = aColor[1] = aColor[2] = aColor[3] = 1.f; if(q->m_ColorEnv >= 0) { - EnvelopeEval(q->m_ColorEnvOffset / 1000.0f, q->m_ColorEnv, aColor, this); + EnvelopeEval(q->m_ColorEnvOffset, q->m_ColorEnv, aColor, this); } float OffsetX = 0; @@ -1389,7 +1405,7 @@ void CMapLayers::RenderQuadLayer(int LayerIndex, CMapItemLayerQuads *pQuadLayer, if(q->m_PosEnv >= 0) { float aChannels[4]; - EnvelopeEval(q->m_PosEnvOffset / 1000.0f, q->m_PosEnv, aChannels, this); + EnvelopeEval(q->m_PosEnvOffset, q->m_PosEnv, aChannels, this); OffsetX = aChannels[0]; OffsetY = aChannels[1]; Rot = aChannels[2] / 180.0f * pi; diff --git a/src/game/client/components/maplayers.h b/src/game/client/components/maplayers.h index d6f6e0633..4a3d4bcdf 100644 --- a/src/game/client/components/maplayers.h +++ b/src/game/client/components/maplayers.h @@ -151,7 +151,7 @@ public: void EnvelopeUpdate(); - static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser); + static void EnvelopeEval(int TimeOffsetMillis, int Env, float *pChannels, void *pUser); }; #endif diff --git a/src/game/client/components/mapsounds.cpp b/src/game/client/components/mapsounds.cpp index eec4163fa..ef36b31f0 100644 --- a/src/game/client/components/mapsounds.cpp +++ b/src/game/client/components/mapsounds.cpp @@ -199,7 +199,7 @@ void CMapSounds::OnRender() if(pVoice->m_pSource->m_PosEnv >= 0) { float aChannels[4]; - CMapLayers::EnvelopeEval(pVoice->m_pSource->m_PosEnvOffset / 1000.0f, pVoice->m_pSource->m_PosEnv, aChannels, m_pClient->m_pMapLayersBackGround); + CMapLayers::EnvelopeEval(pVoice->m_pSource->m_PosEnvOffset, pVoice->m_pSource->m_PosEnv, aChannels, m_pClient->m_pMapLayersBackGround); OffsetX = aChannels[0]; OffsetY = aChannels[1]; } @@ -218,7 +218,7 @@ void CMapSounds::OnRender() if(pVoice->m_pSource->m_SoundEnv >= 0) { float aChannels[4]; - CMapLayers::EnvelopeEval(pVoice->m_pSource->m_SoundEnvOffset / 1000.0f, pVoice->m_pSource->m_SoundEnv, aChannels, m_pClient->m_pMapLayersBackGround); + CMapLayers::EnvelopeEval(pVoice->m_pSource->m_SoundEnvOffset, pVoice->m_pSource->m_SoundEnv, aChannels, m_pClient->m_pMapLayersBackGround); float Volume = clamp(aChannels[0], 0.0f, 1.0f); Sound()->SetVoiceVolume(pVoice->m_Voice, Volume); diff --git a/src/game/client/render.h b/src/game/client/render.h index 1b3838329..2fd641143 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -39,7 +39,7 @@ enum TILERENDERFLAG_EXTEND = 4, }; -typedef void (*ENVELOPE_EVAL)(float TimeOffset, int Env, float *pChannels, void *pUser); +typedef void (*ENVELOPE_EVAL)(int TimeOffsetMillis, int Env, float *pChannels, void *pUser); class CRenderTools { @@ -83,7 +83,7 @@ public: void RenderTee(class CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, float Alpha = 1.0f); // map render methods (gc_render_map.cpp) - static void RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult); + static void RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, int64 TimeMicros, float *pResult); void RenderQuads(CQuad *pQuads, int NumQuads, int Flags, ENVELOPE_EVAL pfnEval, void *pUser); void ForceRenderQuads(CQuad *pQuads, int NumQuads, int Flags, ENVELOPE_EVAL pfnEval, void *pUser, float Alpha = 1.0f); void RenderTilemap(CTile *pTiles, int w, int h, float Scale, ColorRGBA Color, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset); diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp index c098109ae..bd0c196d0 100644 --- a/src/game/client/render_map.cpp +++ b/src/game/client/render_map.cpp @@ -11,7 +11,7 @@ #include #include -void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult) +void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, int64 TimeMicros, float *pResult) { if(NumPoints == 0) { @@ -31,13 +31,16 @@ void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Cha return; } - Time = fmod(Time, pPoints[NumPoints - 1].m_Time / 1000.0f) * 1000.0f; + int64 MaxPointTime = (int64)pPoints[NumPoints - 1].m_Time * 1000ll; + TimeMicros = TimeMicros % MaxPointTime; + + int TimeMillis = (int)(TimeMicros / 1000ll); for(int i = 0; i < NumPoints - 1; i++) { - if(Time >= pPoints[i].m_Time && Time <= pPoints[i + 1].m_Time) + if(TimeMillis >= pPoints[i].m_Time && TimeMillis <= pPoints[i + 1].m_Time) { float Delta = pPoints[i + 1].m_Time - pPoints[i].m_Time; - float a = (Time - pPoints[i].m_Time) / Delta; + float a = (float)(((double)TimeMicros / 1000.0) - pPoints[i].m_Time) / Delta; if(pPoints[i].m_Curvetype == CURVETYPE_SMOOTH) a = -2 * a * a * a + 3 * a * a; // second hermite basis @@ -102,7 +105,7 @@ void CRenderTools::ForceRenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags if(q->m_ColorEnv >= 0) { float aChannels[4]; - pfnEval(q->m_ColorEnvOffset / 1000.0f, q->m_ColorEnv, aChannels, pUser); + pfnEval(q->m_ColorEnvOffset, q->m_ColorEnv, aChannels, pUser); r = aChannels[0]; g = aChannels[1]; b = aChannels[2]; @@ -133,7 +136,7 @@ void CRenderTools::ForceRenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags if(q->m_PosEnv >= 0) { float aChannels[4]; - pfnEval(q->m_PosEnvOffset / 1000.0f, q->m_PosEnv, aChannels, pUser); + pfnEval(q->m_PosEnvOffset, q->m_PosEnv, aChannels, pUser); OffsetX = aChannels[0]; OffsetY = aChannels[1]; Rot = aChannels[2] / 360.0f * pi * 2; @@ -190,7 +193,7 @@ void CRenderTools::RenderTileRectangle(int RectX, int RectY, int RectW, int Rect if(ColorEnv >= 0) { float aChannels[4]; - pfnEval(ColorEnvOffset / 1000.0f, ColorEnv, aChannels, pUser); + pfnEval(ColorEnvOffset, ColorEnv, aChannels, pUser); r = aChannels[0]; g = aChannels[1]; b = aChannels[2]; @@ -266,7 +269,7 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color if(ColorEnv >= 0) { float aChannels[4]; - pfnEval(ColorEnvOffset / 1000.0f, ColorEnv, aChannels, pUser); + pfnEval(ColorEnvOffset, ColorEnv, aChannels, pUser); r = aChannels[0]; g = aChannels[1]; b = aChannels[2]; diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 67f86868e..6247148d6 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -280,7 +280,7 @@ void CEditorImage::AnalyseTileFlags() } } -void CEditor::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) +void CEditor::EnvelopeEval(int TimeOffsetMillis, int Env, float *pChannels, void *pUser) { CEditor *pThis = (CEditor *)pUser; if(Env < 0 || Env >= pThis->m_Map.m_lEnvelopes.size()) @@ -293,7 +293,7 @@ void CEditor::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pU } CEnvelope *e = pThis->m_Map.m_lEnvelopes[Env]; - float t = pThis->m_AnimateTime + TimeOffset; + float t = pThis->m_AnimateTime + (TimeOffsetMillis / 1000.0f); t *= pThis->m_AnimateSpeed; e->Eval(t, pChannels); } diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 3774e5eba..e047c12de 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -89,7 +89,7 @@ public: int Eval(float Time, float *pResult) { - CRenderTools::RenderEvalEnvelope(m_lPoints.base_ptr(), m_lPoints.size(), m_Channels, Time, pResult); + CRenderTools::RenderEvalEnvelope(m_lPoints.base_ptr(), m_lPoints.size(), m_Channels, (int64)((double)Time * 1000000.0), pResult); return m_Channels; } @@ -944,7 +944,7 @@ public: CEditorMap m_Map; int m_ShiftBy; - static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser); + static void EnvelopeEval(int TimeOffsetMillis, int Env, float *pChannels, void *pUser); float m_CommandBox; char m_aSettingsCommand[256]; diff --git a/src/game/editor/layer_sounds.cpp b/src/game/editor/layer_sounds.cpp index c9805858f..22e38ffe4 100644 --- a/src/game/editor/layer_sounds.cpp +++ b/src/game/editor/layer_sounds.cpp @@ -35,7 +35,7 @@ void CLayerSounds::Render(bool Tileset) if(pSource->m_PosEnv >= 0) { float aChannels[4]; - m_pEditor->EnvelopeEval(pSource->m_PosEnvOffset / 1000.0f, pSource->m_PosEnv, aChannels, m_pEditor); + m_pEditor->EnvelopeEval(pSource->m_PosEnvOffset, pSource->m_PosEnv, aChannels, m_pEditor); OffsetX = aChannels[0]; OffsetY = aChannels[1]; } @@ -87,7 +87,7 @@ void CLayerSounds::Render(bool Tileset) if(pSource->m_PosEnv >= 0) { float aChannels[4]; - m_pEditor->EnvelopeEval(pSource->m_PosEnvOffset / 1000.0f, pSource->m_PosEnv, aChannels, m_pEditor); + m_pEditor->EnvelopeEval(pSource->m_PosEnvOffset, pSource->m_PosEnv, aChannels, m_pEditor); OffsetX = aChannels[0]; OffsetY = aChannels[1]; }