Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.83 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement