Very small OpenGL wrapper (before moggle was there)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

161 lines
3.8 KiB

//
// interpolator.h
// J
//
// Created by Joshua Moerman on 9/2/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef J_interpolator_h
#define J_interpolator_h
#include <tr1/functional>
namespace J {
namespace interpolator_details {
// some templates to handle arrays...
template <typename Scalar, typename T>
void interpolate(Scalar const & ratio, T & value, T const & begin_value, T const & end_value){
value = (Scalar(1.0) - ratio)*begin_value + ratio*end_value;
}
template <typename Scalar, typename T, size_t N>
void interpolate(Scalar const & ratio, T (& value)[N], T const (& begin_value)[N], T const (& end_value)[N]){
for (unsigned int i = 0; i < N; ++i)
value[i] = (Scalar(1.0) - ratio)*begin_value[i] + ratio*end_value[i];
}
template <typename Scalar, typename T, size_t N>
void interpolate(Scalar const & ratio, std::array<T, N> & value, std::array<T, N> const & begin_value, std::array<T, N> const & end_value){
for (unsigned int i = 0; i < N; ++i)
value[i] = (Scalar(1.0) - ratio)*begin_value[i] + ratio*end_value[i];
}
template <typename T>
struct scalar_of {
// TODO: find out how to make it work for user-types
// maybe require T::Scalar
typedef T type;
};
template <typename T, size_t N>
struct scalar_of<T[N]> {
typedef typename scalar_of<T>::type type;
};
template <typename T, size_t N>
struct scalar_of<std::array<T, N> > {
typedef typename scalar_of<T>::type type;
};
}
namespace interpolators {
struct linear{
template <typename T>
T operator()(T x){
return x;
}
};
struct cubic_in_out{
template <typename T>
T operator()(T x){
return 3*x*x - 2*x*x*x;
}
};
struct quintic_in_out{
template <typename T>
T operator()(T x){
return 6*x*x*x*x*x - 15*x*x*x*x + 10*x*x*x;
return x*x*x*(x*(x*6-15)+10);
}
};
struct cosine_in_out{
template <typename T>
T operator()(T x){
return 0.5f - 0.5f*std::cos(x*M_PI);
}
};
}
template <typename T>
class interpolator {
typedef typename interpolator_details::scalar_of<T>::type Scalar;
typedef std::tr1::function<Scalar (Scalar)> EaseFunction;
EaseFunction ease_function;
size_t length;
size_t steps;
T value;
T begin_value;
T end_value;
public:
template <typename S>
interpolator(S const & begin_value_, size_t length_ = 30) :
ease_function(interpolators::cubic_in_out())
, length(length_)
, steps(length_)
, value(begin_value_)
, begin_value(begin_value_)
, end_value(begin_value_) {}
template <typename S, typename F>
interpolator(S const & begin_value_, size_t length_, F const & ease_function_) :
ease_function(ease_function_)
, length(length_)
, steps(0)
, value(begin_value_)
, begin_value(begin_value_)
, end_value(begin_value_) {}
operator T const & () const{
return value;
}
T const & get_value() const{
return value;
}
void set_value(T const & new_value){
begin_value = value;
end_value = new_value;
steps = 0;
}
// FIXME: temporary hack
template <size_t N>
void set_value(Scalar const (& new_value)[N]){
begin_value = value;
for(unsigned int i = 0; i < N; ++i)
end_value[i] = new_value[i];
steps = 0;
}
void set_length(size_t new_length){
Scalar ratio = (Scalar) steps / (Scalar) length;
length = new_length;
steps = ratio*length;
}
template <typename F>
void set_ease_function(F const & new_ease_function){
ease_function = new_ease_function;
}
void interpolate(){
if(steps >= length) return;
++steps;
Scalar ratio = (Scalar) steps / (Scalar) length;
ratio = ease_function(ratio);
interpolator_details::interpolate(ratio, value, begin_value, end_value);
}
};
} // namespace J
#endif