123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _INTERPOLATEDCHANGEPROPERTY_H_
- #define _INTERPOLATEDCHANGEPROPERTY_H_
- #ifndef _SIM_H_
- #include "console/sim.h"
- #endif
- #ifndef _MEASE_H_
- #include "math/mEase.h"
- #endif
- #ifndef _TIMESOURCE_H_
- #include "core/util/timeSource.h"
- #endif
- /// A property that smoothly transitions to new values instead of assuming
- /// them right away.
- ///
- /// @param T Value type. Must have "interpolate( from, to, factor )" method.
- /// @param TimeSource Time source to which interpolation is synchronized.
- template< typename T, class TimeSource = GenericTimeSource< SimMSTimer > >
- class InterpolatedChangeProperty
- {
- public:
- enum
- {
- /// Default time (in milliseconds) to go from one value
- /// to a new one.
- DEFAULT_TRANSITION_TIME = 2000
- };
- typedef TimeSource TimeSourceType;
- typedef typename TimeSource::TickType TimeType;
- protected:
- /// The current value.
- mutable T mCurrentValue;
- /// @name Transitioning
- ///
- /// Transitioning allows to smoothly go from one value to
- /// a different one over a period of time.
- ///
- /// @{
- ///
- TimeSourceType mTimeSource;
- /// Number of milliseconds it takes to go from one value
- /// to a different one.
- TimeType mBlendPhaseTime;
- /// Interpolation to use for going from source to target.
- EaseF mTransitionCurve;
- /// The time the transition started. If 0, no transition is in progress.
- mutable TimeType mTransitionStartTime;
- /// The value we are transitioning from.
- T mSourceValue;
- /// The value we are transitioning to.
- T mTargetValue;
- /// @}
- /// Update #mCurrentValue.
- void _update() const;
- public:
- ///
- InterpolatedChangeProperty( const T& initialValue = T() )
- : mCurrentValue( initialValue ),
- mBlendPhaseTime( DEFAULT_TRANSITION_TIME ),
- mTargetValue( initialValue ),
- mTransitionStartTime( 0 )
- {
- // By default, start time source right away.
- mTimeSource.start();
- }
- /// Get the current value. If a transition is in progress, this will be
- /// an interpolation of the last value and the new one.
- const T& getCurrentValue() const
- {
- _update();
- return mCurrentValue;
- }
- /// Set the interpolation to use for going from one ambient color to
- /// a different one.
- void setTransitionCurve( const EaseF& ease ) { mTransitionCurve = ease; }
- /// Set the amount of time it takes to go from one ambient color to
- /// a different one.
- void setTransitionTime( TimeType time ) { mBlendPhaseTime = time; }
- /// Set the desired value. If this differs from the current value,
- /// a smooth blend to the given color will be initiated.
- ///
- /// @param value Desired value.
- void setTargetValue( const T& value );
- /// Return the time source to which interpolation synchronizes.
- const TimeSourceType& geTimeSource() const { return mTimeSource; }
- TimeSourceType& getTimeSource() { return mTimeSource; }
- };
- //-----------------------------------------------------------------------------
- template< typename T, typename TimeSource >
- void InterpolatedChangeProperty< T, TimeSource >::setTargetValue( const T& value )
- {
- if( mTargetValue == value )
- return;
- if( mBlendPhaseTime == 0 )
- {
- mTargetValue = value;
- mCurrentValue = value;
- }
- else
- {
- // Set the source value to the current value (which may be interpolated)
- // and then start a transition to the given target.
- mSourceValue = getCurrentValue();
- mTargetValue = value;
- mTransitionStartTime = mTimeSource.getPosition();
- }
- }
- //-----------------------------------------------------------------------------
- template< typename T, typename TimeSource >
- void InterpolatedChangeProperty< T, TimeSource >::_update() const
- {
- // Nothing to do if no transition in progress.
- if( !mTransitionStartTime )
- return;
- // See if we have finished the transition.
- TimeType deltaTime = mTimeSource.getPosition() - mTransitionStartTime;
- if( deltaTime >= mBlendPhaseTime )
- {
- // We're done.
- mCurrentValue = mTargetValue;
- mTransitionStartTime = 0;
- return;
- }
- // Determine the interpolated value.
- F32 blendFactor = F32( deltaTime ) / F32( mBlendPhaseTime );
- blendFactor = mTransitionCurve.getUnitValue( blendFactor );
- mCurrentValue.interpolate( mSourceValue, mTargetValue, blendFactor );
- }
- #endif // !_INTERPOLATEDCHANGEPROPERTY_H_
|