From 4be5ee9b6172b73eb49a8b5afe65afdd60ef2f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Wed, 27 Oct 2021 00:32:40 +0200 Subject: [PATCH] Enable prediction on SP --- code/game/src/prediction.c | 234 ++++++++++++++------------- code/modules/source/system_vehicle.c | 3 +- 2 files changed, 122 insertions(+), 115 deletions(-) diff --git a/code/game/src/prediction.c b/code/game/src/prediction.c index 63a0a5c..beea798 100644 --- a/code/game/src/prediction.c +++ b/code/game/src/prediction.c @@ -1,114 +1,120 @@ -#include "zpl.h" -#include "prediction.h" -#include "platform.h" -#include "world/world.h" -#include "game.h" - -#define PREDICT_SMOOTH_FACTOR_LO 0.10 -#define PREDICT_SMOOTH_FACTOR_HI 0.01 - -static inline float map_factor(float x) { - x = 1.0f - zpl_clamp01(x); - return 1.0f - x*x*x*x*x*x*x*x; -} - -static inline float base_angle(float x) { - while (x > ZPL_TAU) x -= ZPL_TAU; - while (x < 0.0f) x += ZPL_TAU; - return x; -} - -static inline float spherical_lerp(float a, float b, float t) { - a = base_angle(a); - b = base_angle(b); - float d = b - a; - - if (d < -ZPL_PI) { - b += ZPL_TAU; - } else if (d > ZPL_PI) { - b -= ZPL_TAU; - } - - return base_angle(zpl_lerp(a, b, t)); -} - -float smooth_val(float cur, float tgt, uint64_t dt) { - float factor = zpl_clamp01(map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS))); - -#if 0 - dt = 200; - factor = map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS)); - zpl_printf("lerp factor: %f\n", factor); - zpl_exit(0); -#endif - - return zpl_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_LO, PREDICT_SMOOTH_FACTOR_HI, factor)); -} - -float smooth_val_spherical(float cur, float tgt, uint64_t dt) { - float factor = zpl_clamp01(map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS))); - - return spherical_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_LO, PREDICT_SMOOTH_FACTOR_HI, factor)); -} - -void predict_receive_update(entity_view *d, entity_view *data) { - if (d && data->flag & EFLAG_INTERP) { - // NOTE(zaklaus): store target pos but keep x,y unchanged - float tx = data->x; - float ty = data->y; - float theading = data->heading; - data->x = d->x; - data->y = d->y; - data->heading = d->heading; - data->tx = tx; - data->ty = ty; - data->theading = theading; - } - - data->tran_effect = d->tran_effect; - data->tran_time = d->tran_time; -} - - -void lerp_entity_positions(uint64_t key, entity_view *data) { - (void)key; - world_view *view = game_world_view_get_active(); - - if (data->flag == EFLAG_INTERP) { - if (game_get_kind() == GAMEKIND_CLIENT) { - data->x = smooth_val(data->x, data->tx, view->delta_time[data->layer_id]); - data->y = smooth_val(data->y, data->ty, view->delta_time[data->layer_id]); - data->heading = smooth_val_spherical(data->heading, data->theading, view->delta_time[data->layer_id]); - } else { - (void)view; - data->x = data->tx; - data->y = data->ty; - data->heading = data->theading; - } - } -} - -void do_entity_fadeinout(uint64_t key, entity_view * data) { - (void)key; - switch (data->tran_effect) { - case ETRAN_FADEIN: { - data->tran_time += platform_frametime(); - - if (data->tran_time > 1.0f) { - data->tran_effect = ETRAN_NONE; - data->tran_time = 1.0f; - } - }break; - - case ETRAN_FADEOUT: { - data->tran_time -= platform_frametime(); - - if (data->tran_time < 0.0f) { - data->tran_effect = ETRAN_REMOVE; - data->tran_time = 0.0f; - } - }break; - - default: break; - } -} +#include "zpl.h" +#include "prediction.h" +#include "platform.h" +#include "world/world.h" +#include "game.h" + +#define PREDICT_SMOOTH_FACTOR_LO 0.10 +#define PREDICT_SMOOTH_FACTOR_HI 0.01 + +static inline float map_factor(float x) { + x = 1.0f - zpl_clamp01(x); + return 1.0f - x*x*x*x*x*x*x*x; +} + +static inline float base_angle(float x) { + while (x > ZPL_TAU) x -= ZPL_TAU; + while (x < 0.0f) x += ZPL_TAU; + return x; +} + +static inline float spherical_lerp(float a, float b, float t) { + a = base_angle(a); + b = base_angle(b); + float d = b - a; + + if (d < -ZPL_PI) { + b += ZPL_TAU; + } else if (d > ZPL_PI) { + b -= ZPL_TAU; + } + + return base_angle(zpl_lerp(a, b, t)); +} + +float smooth_val(float cur, float tgt, uint64_t dt) { + float factor = zpl_clamp01(map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS))); + +#if 0 + dt = 200; + factor = map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS)); + zpl_printf("lerp factor: %f\n", factor); + zpl_exit(0); +#endif + + return zpl_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_LO, PREDICT_SMOOTH_FACTOR_HI, factor)); +} + +float smooth_val_spherical(float cur, float tgt, uint64_t dt) { + float factor = zpl_clamp01(map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_MP_FAST_MS, WORLD_TRACKER_UPDATE_MP_SLOW_MS))); + + return spherical_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_LO, PREDICT_SMOOTH_FACTOR_HI, factor)); +} + +void predict_receive_update(entity_view *d, entity_view *data) { + if (d && data->flag & EFLAG_INTERP) { + // NOTE(zaklaus): store target pos but keep x,y unchanged + float tx = data->x; + float ty = data->y; + float theading = data->heading; + data->x = d->x; + data->y = d->y; + data->heading = d->heading; + data->tx = tx; + data->ty = ty; + data->theading = theading; + } + + data->tran_effect = d->tran_effect; + data->tran_time = d->tran_time; +} + +#define ENTITY_DO_LERP_SP 1 + +void lerp_entity_positions(uint64_t key, entity_view *data) { + (void)key; + world_view *view = game_world_view_get_active(); + + if (data->flag == EFLAG_INTERP) { +#if ENTITY_DO_LERP_SP==0 + if (game_get_kind() == GAMEKIND_CLIENT) +#else + if (1) +#endif + { + data->x = smooth_val(data->x, data->tx, view->delta_time[data->layer_id]); + data->y = smooth_val(data->y, data->ty, view->delta_time[data->layer_id]); + data->heading = smooth_val_spherical(data->heading, data->theading, view->delta_time[data->layer_id]); + } else { + (void)view; + data->x = data->tx; + data->y = data->ty; + data->heading = data->theading; + } + } +} + +void do_entity_fadeinout(uint64_t key, entity_view * data) { + (void)key; + switch (data->tran_effect) { + case ETRAN_FADEIN: { + data->tran_time += platform_frametime(); + + if (data->tran_time > 1.0f) { + data->tran_effect = ETRAN_NONE; + data->tran_time = 1.0f; + } + }break; + + case ETRAN_FADEOUT: { + data->tran_time -= platform_frametime(); + + if (data->tran_time < 0.0f) { + data->tran_effect = ETRAN_REMOVE; + data->tran_time = 0.0f; + } + }break; + + default: break; + } +} diff --git a/code/modules/source/system_vehicle.c b/code/modules/source/system_vehicle.c index 1ef12b1..fc51e3f 100644 --- a/code/modules/source/system_vehicle.c +++ b/code/modules/source/system_vehicle.c @@ -173,7 +173,8 @@ void VehicleHandling(ecs_iter_t *it) { { float dx = zpl_sin(car->heading); float dy = -zpl_cos(car->heading); - debug_push_circle((debug_v2){p[i].x+dx*car->steer*-20, p[i].y+dy*car->steer*-20}, 5.0f, 0x00FFAAFF); + float steer_mult = -80.0f; + debug_push_circle((debug_v2){p[i].x+dx*car->steer*steer_mult, p[i].y+dy*car->steer*steer_mult}, 5.0f, 0x00FFAAFF); } } }