Torque3D Documentation / _generateds / interpolatedChangeProperty.h

interpolatedChangeProperty.h

Engine/source/util/interpolatedChangeProperty.h

More...

Classes:

class

A property that smoothly transitions to new values instead of assuming them right away.

Detailed Description

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