fork download
  1. //Returns the hill of a specific bounce, working backwards and excluding the final half-bounce.
  2. //0 = the last bounce, excluding the final half-bounce.
  3. //1 = the second-to-last bounce.
  4. float priv_Bounce_GetBounceWidth(unsigned bounce)
  5. {
  6. //Each bounce is half the width of the previous bounce.
  7. //The first bounce (excluding the half-bounce) is 1.0f,
  8. //The second bounce is 0.5f, the third is 0.25f, and so on.
  9. return std::pow(0.5f, float(bounce));
  10. }
  11.  
  12. //Returns the height of a specific bounce, working backwards and excluding the final half-bounce.
  13. //0 = the last bounce, excluding the final half-bounce.
  14. //1 = the second-to-last bounce.
  15. //
  16. //'bounciness' is a value from 0.0 to 1.0, describing how (from the half-bounce on down)
  17. //small the size of each bounce becomes, relative to the previous.
  18. float priv_Bounce_GetBounceHeight(unsigned bounce, float bounciness)
  19. {
  20. return std::pow(bounciness, float(bounce+1));
  21. }
  22.  
  23. float priv_Bounce_GetBouncePosition(unsigned bounce)
  24. {
  25. float position = 1.0f; //The final half-bounce.
  26. for(unsigned i = 0; i < bounce; i++)
  27. {
  28. //Add up the width of all the bounces before this one.
  29. position += priv_Bounce_GetBounceWidth(i);
  30. }
  31.  
  32. return position;
  33. }
  34.  
  35. float priv_Bounce_GetBounceHalfwayPoint(unsigned bounce)
  36. {
  37. return (priv_Bounce_GetBouncePosition(bounce) + (priv_Bounce_GetBounceWidth(bounce) * 0.5f));
  38. }
  39.  
  40. //Gets the amount we need to offset the bounces by, to make them be at the 'bottom' of the ease.
  41. float priv_Bounce_GetVerticalBounceOffset(unsigned bounce, float bounciness)
  42. {
  43. const float inverseBounciness = (1.0f - bounciness);
  44. float offset = 0.0f;
  45.  
  46. for(unsigned i = 0; i <= bounce; i++)
  47. {
  48. //For each bounce, add 0.75f (or whatever (1.0f - bounciness) is) of the remaining height. (Since Each bounce is 0.25f of the previous).
  49. offset += (inverseBounciness * (1.0f - offset));
  50. }
  51.  
  52. return offset;
  53. }
  54.  
  55. //Returns the total width of all the bounces, plus the final half-bounce.
  56. float priv_Bounce_TotalWidth(unsigned bounces)
  57. {
  58. float totalWidth = 1.0f; //The final half-bounce.
  59. for(unsigned bounce = 0; bounce < bounces; bounce++)
  60. {
  61. //The First bounce added, adds '1.0f'. Second bounce adds '0.5f', the next adds '0.25f', and so on.
  62. totalWidth += priv_Bounce_GetBounceWidth(bounce);
  63. }
  64.  
  65. return totalWidth;
  66. }
  67.  
  68. float CustomBounceEase(float position, int bounces, float bounciness)
  69. {
  70. //Optimization for end points, which are the most common spots.
  71. if(position == 0.0f || position == 1.0f)
  72. {
  73. return position;
  74. }
  75.  
  76. //I don't know the purpose this constant serves in the original ease equation.
  77. const float UnknownVar = 7.5625f;
  78.  
  79. //Calculate the total width needed for all the bounces.
  80. const float TotalWidth = priv_Bounce_TotalWidth(bounces);
  81.  
  82. for(unsigned int bounce = bounces; bounce-- > 0; )
  83. {
  84. float bouncePos = priv_Bounce_GetBouncePosition(bounce);
  85.  
  86. if(position > (bouncePos / TotalWidth))
  87. {
  88. position -= (priv_Bounce_GetBounceHalfwayPoint(bounce) / TotalWidth);
  89. float verticalOffset = priv_Bounce_GetVerticalBounceOffset(bounce, bounciness);
  90.  
  91. return ((UnknownVar * position * position) + verticalOffset);
  92. }
  93. }
  94.  
  95. //The final half-bounce:
  96. return (UnknownVar * position * position);
  97. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty