Skip to content

Commit d3292f8

Browse files
committed
bugfix(anim): Fix elapsed time of object animations
1 parent cb57c1b commit d3292f8

File tree

4 files changed

+36
-7
lines changed

4 files changed

+36
-7
lines changed

Core/Libraries/Source/WWVegas/WW3D2/seglinerenderer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ SegLineRendererClass::SegLineRendererClass(void) :
7878
NoiseAmplitude(0.0f),
7979
MergeAbortFactor(1.5f),
8080
TextureTileFactor(1.0f),
81+
LastUsedSyncTime(WW3D::Get_Logic_Time_Milliseconds()),
8182
CurrentUVOffset(0.0f,0.0f),
8283
UVOffsetDeltaPerMS(0.0f, 0.0f),
8384
Bits(DEFAULT_BITS),
@@ -97,6 +98,7 @@ SegLineRendererClass::SegLineRendererClass(const SegLineRendererClass & that) :
9798
NoiseAmplitude(0.0f),
9899
MergeAbortFactor(1.5f),
99100
TextureTileFactor(1.0f),
101+
LastUsedSyncTime(that.LastUsedSyncTime),
100102
CurrentUVOffset(0.0f,0.0f),
101103
UVOffsetDeltaPerMS(0.0f, 0.0f),
102104
Bits(DEFAULT_BITS),
@@ -118,6 +120,7 @@ SegLineRendererClass & SegLineRendererClass::operator = (const SegLineRendererCl
118120
NoiseAmplitude = that.NoiseAmplitude;
119121
MergeAbortFactor = that.MergeAbortFactor;
120122
TextureTileFactor = that.TextureTileFactor;
123+
LastUsedSyncTime = that.LastUsedSyncTime;
121124
CurrentUVOffset = that.CurrentUVOffset;
122125
UVOffsetDeltaPerMS = that.UVOffsetDeltaPerMS;
123126
Bits = that.Bits;
@@ -198,6 +201,7 @@ void SegLineRendererClass::Set_Texture_Tile_Factor(float factor)
198201

199202
void SegLineRendererClass::Reset_Line(void)
200203
{
204+
LastUsedSyncTime = WW3D::Get_Logic_Time_Milliseconds();
201205
CurrentUVOffset.Set(0.0f,0.0f);
202206
}
203207

@@ -224,14 +228,16 @@ void SegLineRendererClass::Render
224228
** Handle texture UV offset animation (done once for entire line).
225229
*/
226230
// TheSuperHackers @tweak The render update is now decoupled from the logic step.
227-
Vector2 uv_offset = CurrentUVOffset + UVOffsetDeltaPerMS * WW3D::Get_Logic_Frame_Time_Milliseconds();
231+
const unsigned int delta = WW3D::Get_Logic_Time_Milliseconds() - LastUsedSyncTime;
232+
Vector2 uv_offset = CurrentUVOffset + UVOffsetDeltaPerMS * (float)delta;
228233

229234
// ensure offsets are in [0, 1] range:
230235
uv_offset.X = uv_offset.X - floorf(uv_offset.X);
231236
uv_offset.Y = uv_offset.Y - floorf(uv_offset.Y);
232237

233238
// Update state
234239
CurrentUVOffset = uv_offset;
240+
LastUsedSyncTime = WW3D::Get_Logic_Time_Milliseconds();
235241

236242
// Used later
237243
TextureMapMode map_mode = Get_Texture_Mapping_Mode();

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/animobj.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Animatable3DObjClass::Animatable3DObjClass(const char * htree_name) :
8989
ModeAnim.Motion=NULL;
9090
ModeAnim.Frame=0.0f;
9191
ModeAnim.PrevFrame=0.0f;
92+
ModeAnim.LastSyncTime=WW3D::Get_Logic_Time_Milliseconds();
9293
ModeAnim.frameRateMultiplier=1.0; // 020607 srj -- added
9394
ModeAnim.animDirection=1.0; // 020607 srj -- added
9495
ModeInterp.Motion0=NULL;
@@ -144,6 +145,7 @@ Animatable3DObjClass::Animatable3DObjClass(const Animatable3DObjClass & src) :
144145
ModeAnim.Motion=NULL;
145146
ModeAnim.Frame=0.0f;
146147
ModeAnim.PrevFrame=0.0f;
148+
ModeAnim.LastSyncTime=WW3D::Get_Logic_Time_Milliseconds();
147149
ModeAnim.frameRateMultiplier=1.0; // 020607 srj -- added
148150
ModeAnim.animDirection=1.0; // 020607 srj -- added
149151
ModeInterp.Motion0=NULL;
@@ -203,6 +205,7 @@ Animatable3DObjClass & Animatable3DObjClass::operator = (const Animatable3DObjCl
203205
ModeAnim.Motion = NULL;
204206
ModeAnim.Frame = 0.0f;
205207
ModeAnim.PrevFrame = 0.0f;
208+
ModeAnim.LastSyncTime = WW3D::Get_Logic_Time_Milliseconds();
206209
ModeAnim.frameRateMultiplier=1.0; // 020607 srj -- added
207210
ModeAnim.animDirection=1.0; // 020607 srj -- added
208211
ModeInterp.Motion0 = NULL;
@@ -471,6 +474,7 @@ void Animatable3DObjClass::Set_Animation(HAnimClass * motion, float frame, int m
471474
ModeAnim.Motion = motion;
472475
ModeAnim.PrevFrame = ModeAnim.Frame;
473476
ModeAnim.Frame = frame;
477+
ModeAnim.LastSyncTime = WW3D::Get_Logic_Time_Milliseconds();
474478
ModeAnim.frameRateMultiplier=1.0; // 020607 srj -- added
475479
ModeAnim.animDirection=1.0; // 020607 srj -- added
476480

@@ -947,13 +951,14 @@ float Animatable3DObjClass::Compute_Current_Frame(float *newDirection) const
947951
{
948952
frame = ModeAnim.Frame;
949953

950-
//
951-
// Compute the current frame based on elapsed time.
952-
//
953954
if (ModeAnim.AnimMode != ANIM_MODE_MANUAL) {
955+
//
956+
// Compute the current frame based on elapsed time.
957+
// TheSuperHackers @info Is using elapsed time because frame computation is not guaranteed to be called every render frame!
958+
//
954959
// TheSuperHackers @tweak The animation render update is now decoupled from the logic step.
955-
const float frametime = WW3D::Get_Logic_Frame_Time_Seconds();
956-
const float delta = ModeAnim.Motion->Get_Frame_Rate() * ModeAnim.frameRateMultiplier * ModeAnim.animDirection * frametime;
960+
const float timeDiff = WW3D::Get_Logic_Time_Milliseconds() - ModeAnim.LastSyncTime;
961+
const float delta = ModeAnim.Motion->Get_Frame_Rate() * ModeAnim.frameRateMultiplier * ModeAnim.animDirection * timeDiff * 0.001f;
957962
frame += delta;
958963

959964
//
@@ -1050,6 +1055,7 @@ void Animatable3DObjClass::Single_Anim_Progress (void)
10501055
//
10511056
ModeAnim.PrevFrame = ModeAnim.Frame;
10521057
ModeAnim.Frame = Compute_Current_Frame(&ModeAnim.animDirection);
1058+
ModeAnim.LastSyncTime = WW3D::Get_Logic_Time_Milliseconds();
10531059
}
10541060

10551061

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/animobj.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class Animatable3DObjClass : public CompositeRenderObjClass
190190
float Frame;
191191
float PrevFrame;
192192
int AnimMode;
193+
int LastSyncTime;
193194
float animDirection;
194195
float frameRateMultiplier; // 020607 srj -- added
195196
} ModeAnim;

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,28 @@ class WW3D
171171
** will control things like animated uv-offset mappers and render object animations.
172172
*/
173173
static void Sync(bool step);
174+
175+
// Total sync time in milliseconds. Advances in full logic time steps only.
174176
static unsigned int Get_Sync_Time(void) { return SyncTime; }
177+
178+
// Current sync frame time in milliseconds. Can be zero when the logic has not stepped forward in the current render update.
175179
static unsigned int Get_Sync_Frame_Time(void) { return SyncTime - PreviousSyncTime; }
176-
static unsigned int Get_Fractional_Sync_Milliseconds() { return FractionalSyncMs; }
180+
181+
// Fractional sync frame time. Accumulates for as long as the sync frame is not stepped forward.
182+
static unsigned int Get_Fractional_Sync_Milliseconds() { return (unsigned int)FractionalSyncMs; }
183+
184+
// Total logic time in milliseconds. Can include fractions of a logic step. Is rounded to integer.
185+
static unsigned int Get_Logic_Time_Milliseconds() { return SyncTime + (unsigned int)FractionalSyncMs; }
186+
187+
// Logic time step in milliseconds. Can be a fraction of a logic step.
177188
static float Get_Logic_Frame_Time_Milliseconds() { return LogicFrameTimeMs; }
189+
190+
// Logic time step in seconds. Can be a fraction of a logic step.
178191
static float Get_Logic_Frame_Time_Seconds() { return LogicFrameTimeMs * 0.001f; }
192+
193+
// Returns the render frame count.
179194
static unsigned int Get_Frame_Count(void) { return FrameCount; }
195+
180196
static unsigned int Get_Last_Frame_Poly_Count(void);
181197
static unsigned int Get_Last_Frame_Vertex_Count(void);
182198

0 commit comments

Comments
 (0)