X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Finterpolator.hh;fp=src%2Fmoof%2Finterpolator.hh;h=937ca8a93f28ecda6d37eba8d258c0b6ff876a2d;hp=0000000000000000000000000000000000000000;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/moof/interpolator.hh b/src/moof/interpolator.hh new file mode 100644 index 0000000..937ca8a --- /dev/null +++ b/src/moof/interpolator.hh @@ -0,0 +1,204 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#ifndef _MOOF_INTERPOLATOR_HH_ +#define _MOOF_INTERPOLATOR_HH_ + +/** + * \file interpolator.hh + * Functions and classes concerning interpolations between values. + */ + +#include + + +namespace moof { + + +/** + * Interpolators should inherit from this base class to get some free + * functionality. Subclasses of this base class will implement their own + * interpolation functions. + */ +template +class interpolator +{ +public: + + /** + * Interpolation mode. + */ + enum mode + { + stop = 0, /// Interpolator will stop when done. + repeat = 1, /// Interpolator will go back to the beginning. + oscillate = 2 /// Interpolator will reverse direction. + }; + + + /** + * Construct an uninitialized interpolator. + */ + interpolator() : + is_done_(true) {} + + /** + * Construct an interpolator. + * \param a The initial value. + * \param b The target value. + * \param t The duration of the interpolation. + * \param mode The interpolation mode. + */ + interpolator(const T& a, const T& b, scalar t = 1.0, mode mode = stop) : + state_(a), + prior_(a), + a_(a), + b_(b), + alpha_(SCALAR(0.0)), + scale_(SCALAR(1.0) / t), + mode_(mode), + is_done_(false) {} + + /** + * Initialize the interpolator. Any interpolation already being + * tracked by this object will be replaced with a new interpolation + * based on the initialization arguments. + * \param a The initial value. + * \param b The target value. + * \param t The duration of the interpolation. + * \param mode The interpolation mode. + */ + void init(const T& a, const T& b, scalar t = 1.0, mode mode = stop) + { + a_ = a; + b_ = b; + alpha_ = 0.0; + scale_ = 1.0 / t; + mode_ = mode; + is_done_ = false; + } + + + /** + * Update the interpolation state with a timeslice. + * \param t The total time in seconds. + * \param dt The number of seconds passed since the last call to + * update. + */ + void update(scalar t, scalar dt) + { + if (!is_done_) + { + alpha_ += dt * scale_; + prior_ = state_; + state_ = function_(a_, b_, alpha_); + + if (alpha_ > 1.0) + { + switch (mode_) + { + case stop: + alpha_ = SCALAR(1.0); + is_done_ = true; + break; + case repeat: + alpha_ -= SCALAR(1.0); + break; + case oscillate: + alpha_ = SCALAR(2.0) - alpha_; + scale_ = -scale_; + break; + } + } + else if (alpha_ < 0.0) + { + switch (mode_) + { + case stop: + alpha_ = SCALAR(0.0); + is_done_ = true; + break; + case repeat: + alpha_ += SCALAR(1.0); + break; + case oscillate: + alpha_ = -alpha_; + scale_ = -scale_; + break; + } + } + } + } + + + /** + * Get the interpolated value. + * \return The interpolated value. + */ + T state() const + { + return state_; + } + + /** + * Get the interpolated value interpolated between two updates. + * \param alpha The fraction between updates. + * \return The interpolated value. + */ + T state(scalar alpha) const + { + return lerp(prior_, state_, alpha); + } + + /** + * Get whether or not the interpolation is done. This will only return + * true if the interpolation mode is stop. + * \return True if the interpolation has finished. + */ + bool is_done() const + { + return is_done_; + } + + +private: + + T state_; + T prior_; + T a_; + T b_; + + F function_; + + scalar alpha_; + scalar scale_; + mode mode_; + bool is_done_; +}; + + +struct linear_interpolation_function +{ + template + T operator () (const T& a, const T& b, scalar alpha) + { + return lerp(a, b, alpha); + } +}; + + +typedef interpolator lerp_scalar; + + +} // namespace moof + +#endif // _MOOF_INTERPOLATOR_HH_ +