interpolatedChangeProperty.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _INTERPOLATEDCHANGEPROPERTY_H_
  23. #define _INTERPOLATEDCHANGEPROPERTY_H_
  24. #ifndef _SIM_H_
  25. #include "console/sim.h"
  26. #endif
  27. #ifndef _MEASE_H_
  28. #include "math/mEase.h"
  29. #endif
  30. #ifndef _TIMESOURCE_H_
  31. #include "core/util/timeSource.h"
  32. #endif
  33. /// A property that smoothly transitions to new values instead of assuming
  34. /// them right away.
  35. ///
  36. /// @param T Value type. Must have "interpolate( from, to, factor )" method.
  37. /// @param TimeSource Time source to which interpolation is synchronized.
  38. template< typename T, class TimeSource = GenericTimeSource< SimMSTimer > >
  39. class InterpolatedChangeProperty
  40. {
  41. public:
  42. enum
  43. {
  44. /// Default time (in milliseconds) to go from one value
  45. /// to a new one.
  46. DEFAULT_TRANSITION_TIME = 2000
  47. };
  48. typedef TimeSource TimeSourceType;
  49. typedef typename TimeSource::TickType TimeType;
  50. protected:
  51. /// The current value.
  52. mutable T mCurrentValue;
  53. /// @name Transitioning
  54. ///
  55. /// Transitioning allows to smoothly go from one value to
  56. /// a different one over a period of time.
  57. ///
  58. /// @{
  59. ///
  60. TimeSourceType mTimeSource;
  61. /// Number of milliseconds it takes to go from one value
  62. /// to a different one.
  63. TimeType mBlendPhaseTime;
  64. /// Interpolation to use for going from source to target.
  65. EaseF mTransitionCurve;
  66. /// The time the transition started. If 0, no transition is in progress.
  67. mutable TimeType mTransitionStartTime;
  68. /// The value we are transitioning from.
  69. T mSourceValue;
  70. /// The value we are transitioning to.
  71. T mTargetValue;
  72. /// @}
  73. /// Update #mCurrentValue.
  74. void _update() const;
  75. public:
  76. ///
  77. InterpolatedChangeProperty( const T& initialValue = T() )
  78. : mCurrentValue( initialValue ),
  79. mBlendPhaseTime( DEFAULT_TRANSITION_TIME ),
  80. mTargetValue( initialValue ),
  81. mTransitionStartTime( 0 )
  82. {
  83. // By default, start time source right away.
  84. mTimeSource.start();
  85. }
  86. /// Get the current value. If a transition is in progress, this will be
  87. /// an interpolation of the last value and the new one.
  88. const T& getCurrentValue() const
  89. {
  90. _update();
  91. return mCurrentValue;
  92. }
  93. /// Set the interpolation to use for going from one ambient color to
  94. /// a different one.
  95. void setTransitionCurve( const EaseF& ease ) { mTransitionCurve = ease; }
  96. /// Set the amount of time it takes to go from one ambient color to
  97. /// a different one.
  98. void setTransitionTime( TimeType time ) { mBlendPhaseTime = time; }
  99. /// Set the desired value. If this differs from the current value,
  100. /// a smooth blend to the given color will be initiated.
  101. ///
  102. /// @param value Desired value.
  103. void setTargetValue( const T& value );
  104. /// Return the time source to which interpolation synchronizes.
  105. const TimeSourceType& geTimeSource() const { return mTimeSource; }
  106. TimeSourceType& getTimeSource() { return mTimeSource; }
  107. };
  108. //-----------------------------------------------------------------------------
  109. template< typename T, typename TimeSource >
  110. void InterpolatedChangeProperty< T, TimeSource >::setTargetValue( const T& value )
  111. {
  112. if( mTargetValue == value )
  113. return;
  114. if( mBlendPhaseTime == 0 )
  115. {
  116. mTargetValue = value;
  117. mCurrentValue = value;
  118. }
  119. else
  120. {
  121. // Set the source value to the current value (which may be interpolated)
  122. // and then start a transition to the given target.
  123. mSourceValue = getCurrentValue();
  124. mTargetValue = value;
  125. mTransitionStartTime = mTimeSource.getPosition();
  126. }
  127. }
  128. //-----------------------------------------------------------------------------
  129. template< typename T, typename TimeSource >
  130. void InterpolatedChangeProperty< T, TimeSource >::_update() const
  131. {
  132. // Nothing to do if no transition in progress.
  133. if( !mTransitionStartTime )
  134. return;
  135. // See if we have finished the transition.
  136. TimeType deltaTime = mTimeSource.getPosition() - mTransitionStartTime;
  137. if( deltaTime >= mBlendPhaseTime )
  138. {
  139. // We're done.
  140. mCurrentValue = mTargetValue;
  141. mTransitionStartTime = 0;
  142. return;
  143. }
  144. // Determine the interpolated value.
  145. F32 blendFactor = F32( deltaTime ) / F32( mBlendPhaseTime );
  146. blendFactor = mTransitionCurve.getUnitValue( blendFactor );
  147. mCurrentValue.interpolate( mSourceValue, mTargetValue, blendFactor );
  148. }
  149. #endif // !_INTERPOLATEDCHANGEPROPERTY_H_