SHARE
TWEET

Untitled

a guest Apr 19th, 2019 83 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2. #ifndef LIB_INTER
  3. #define LIB_INTER
  4.  
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8.  
  9. /////////////////////////////////////////////////////
  10. //
  11. // ENUMS & STRUCTS
  12. //
  13. /////////////////////////////////////////////////////
  14.  
  15. typedef struct lib_inter_interpolator {
  16.     zpl_vec3 start;
  17.     zpl_vec3 target;
  18.     zpl_vec3 error;
  19.     f64 start_time;
  20.     f64 finish_time;
  21.     f32 last_alpha;
  22.     f32 interp_time;
  23. };
  24.  
  25. #ifdef __cplusplus
  26. }
  27. #endif
  28.  
  29. /////////////////////////////////////////////////////
  30. //
  31. // DECL
  32. //
  33. /////////////////////////////////////////////////////
  34.  
  35. lib_inter_interpolator*     lib_inter_create_iterpolator();
  36. void                        lib_inter_destroy_interpolator(lib_inter_interpolator*);
  37.  
  38. zpl_vec3                    lib_inter_interpolate(lib_inter_interpolator*, zpl_vec3);
  39. zpl_vec3                    lib_inter_set_target(lib_inter_interpolator*, zpl_vec3);
  40.  
  41. /////////////////////////////////////////////////////
  42. //
  43. // IMPLEMENTATION
  44. //
  45. /////////////////////////////////////////////////////
  46.  
  47. #ifdef LIB_INTER_IMPLEMENTATION
  48.  
  49. lib_inter_interpolator* lib_inter_create_iterpolator() {
  50.     return (lib_inter_interpolator*)zpl_malloc(sizeof(lib_inter_interpolator));
  51. }
  52.  
  53. void lib_inter_destroy_interpolator(lib_inter_interpolator* interpolator) {
  54.     if (interpolator) {
  55.         zpl_free(zpl_heap(), interpolator);
  56.         interpolator = NULL;
  57.     }
  58. }
  59.  
  60. zpl_vec3 lib_inter_interpolate(lib_inter_interpolator* interp, zpl_vec3 current_val) {
  61.     if (interp->finish_time > 0.0f) {
  62.         f64 current_time = zpl_time_now();
  63.         f32 alpha = zpl_unlerp(current_time, interp->start_time, interp->finish_time);
  64.  
  65.         // Don't let it to overcompensate the error
  66.         alpha = zpl_clamp(alpha, 0.0f, 1.0f);
  67.  
  68.         // Get the current error portion to compensate
  69.         f32 current_alpha = alpha - interp->last_alpha;
  70.         interp->last_alpha = alpha;
  71.  
  72.         zpl_vec3 compensation;
  73.         zpl_vec3_lerp(&compensation, zpl_vec3f_zero(), interp->error, current_alpha);
  74.  
  75.         // If we finished compensating the error, finish it for the next pulse
  76.         if (alpha == 1.0f) {
  77.             interp->finish_time = 0;
  78.         }
  79.  
  80.         zpl_vec3 compensated;
  81.         zpl_vec3_add(&compensated, current_val, compensation);
  82.         return compensated;
  83.     }
  84. }
  85.  
  86. zpl_vec3 lib_inter_set_target(lib_inter_interpolator* interp, zpl_vec3 current_val, zpl_vec3 target_val) {
  87.    
  88.     interp->start = current_val;
  89.     interp->target = target_val;
  90.  
  91.     zpl_vec3 sub_error;
  92.     zpl_vec3_sub(&sub_error, target_val, current_val);
  93.     interp->error = sub_error;
  94.  
  95.     auto error_mag = zpl_vec3_mag(interp->error);
  96.     if (error_mag > 0.1f) {
  97.         interp->start = target_val;
  98.     }
  99.  
  100.     // Apply the error over 250ms (i.e. 2/5 per 100ms )
  101.     zpl_vec3_mul(&interp->error, interp->error, zpl_lerp(0.25f, 1.0f, zpl_clamp01(zpl_unlerp(interp->interp_time, 0.1f, 0.4f))));
  102.  
  103.     interp->start_time  = zpl_time_now();
  104.     interp->finish_time = interp->start_time + interp->interp_time;
  105.     interp->last_alpha  = 0.0f;
  106. }
  107.  
  108. #endif
  109.  
  110. #endif
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top