7 #ifndef LIBALMATH_ALMATH_SCENEGRAPH_QIANIM_H
8 #define LIBALMATH_ALMATH_SCENEGRAPH_QIANIM_H
10 #include <almath/api.h>
13 #include <type_traits>
14 #include <boost/property_tree/ptree.hpp>
15 #include <boost/range/adaptor/map.hpp>
16 #include <boost/range/adaptor/filtered.hpp>
36 template <
typename InputIt,
typename BinaryOperation>
38 BinaryOperation binary_op) {
41 auto next = std::next(first);
42 while (next != last) {
43 binary_op(*first, *next);
56 typename std::enable_if<std::is_floating_point<T>::value, T>::type
58 return pt.get<T>(
"<xmlattr>.abscissaParam");
64 typename std::enable_if<std::is_floating_point<T>::value>::type
66 pt.put<T>(
"<xmlattr>.abscissaParam", abscissa);
71 typename std::enable_if<std::is_floating_point<T>::value, T>::type
73 return pt.get<T>(
"<xmlattr>.ordinateParam");
77 typename std::enable_if<std::is_floating_point<T>::value>::type
79 pt.put<T>(
"<xmlattr>.ordinateParam", ordinate);
88 ALMATH_API
bool is_key(
const ptree::value_type &val);
112 template <
typename T>
113 typename std::enable_if<std::is_floating_point<T>::value,
ptree &>::type
116 Tangent::put_abscissa<T>(tangent, abscissa);
117 Tangent::put_ordinate<T>(tangent, ordinate);
121 template <
typename T>
122 typename std::enable_if<std::is_floating_point<T>::value, T>::type
124 return pt.get<T>(
"<xmlattr>.value");
127 template <
typename T>
128 typename std::enable_if<std::is_floating_point<T>::value>::type
130 pt.put(
"<xmlattr>.value", value);
137 template <
typename T>
138 typename std::enable_if<std::is_floating_point<T>::value>::type
140 T p2_dframe, T,
int p3_frame, T) {
142 auto dframe = p3_frame - p0_frame;
144 throw std::invalid_argument(
145 "successive Key elements shall have increasing frame attributes");
147 if (p1_dframe < 0 || p1_dframe > dframe) {
148 throw std::invalid_argument(
149 "Key has right Tangent with out of bound abscissa attribute");
151 if (p2_dframe > 0 || p2_dframe < -dframe) {
152 throw std::invalid_argument(
153 "Key has left Tangent with out of bound abscissa attribute");
173 template <
typename Scalar,
typename Functor>
174 typename std::enable_if<std::is_floating_point<Scalar>::value>::type
179 Key::get_value<Scalar>(p0_key),
180 Tangent::get_abscissa<Scalar>(p1_tangent),
181 Tangent::get_ordinate<Scalar>(p1_tangent),
182 Tangent::get_abscissa<Scalar>(p2_tangent),
183 Tangent::get_ordinate<Scalar>(p2_tangent),
185 Key::get_value<Scalar>(p3_key));
189 namespace ActuatorCurve {
236 -> boost::select_second_const_range<
237 decltype(boost::adaptors::filter(pt,
Key::is_key))>
239 return boost::adaptors::values(boost::adaptors::filter(pt,
Key::is_key));
243 -> boost::select_second_mutable_range<
244 decltype(boost::adaptors::filter(pt,
Key::is_key))> {
245 auto kv = boost::adaptors::filter(pt,
Key::is_key);
246 return boost::adaptors::values(kv);
251 template <
typename Scalar>
252 typename std::enable_if<std::is_floating_point<Scalar>::value>::type
256 keys.begin(), keys.end(),
257 [](
const ptree &p0_key,
const ptree &p3_key) {
258 Key::apply_cubic_bezier<Scalar>(p0_key, p3_key,
259 Key::check_cubic_bezier<Scalar>);
266 ALMATH_API
bool is_label(
const ptree::value_type &val);
276 ALMATH_API
bool is_labels(
const ptree::value_type &val);
289 -> boost::select_second_const_range<
292 return boost::adaptors::values(boost::adaptors::filter(pt,
Label::is_label));
297 -> boost::select_second_mutable_range<
300 return boost::adaptors::values(kv);
304 namespace Animation {
307 -> boost::select_second_const_range<
309 return boost::adaptors::values(
314 -> boost::select_second_mutable_range<
317 return boost::adaptors::values(kv);
327 const std::string &actuator);
331 -> boost::select_second_const_range<
333 return boost::adaptors::values(
ALMATH_API std::string get_actuator(const ptree &pt)
std::enable_if< std::is_floating_point< Scalar >::value >::type apply_cubic_bezier(const ptree &p0_key, const ptree &p3_key, Functor op)
ALMATH_API bool get_mute(const ptree &pt)
boost::optional< T > optional
std::enable_if< std::is_floating_point< T >::value, ptree & >::type put_tangent(ptree &pt, Side side, T abscissa, T ordinate)
auto get_labels(const ptree &pt) -> boost::select_second_const_range< decltype(boost::adaptors::filter(pt, Labels::is_labels))>
ALMATH_API std::string name(const ptree &pt)
ALMATH_API ptree::size_type erase_tangent(ptree &pt, Side side)
ALMATH_API bool is_label(const ptree::value_type &val)
ALMATH_API ptree & add_label(ptree &pt, int frame, const std::string value)
std::enable_if< std::is_floating_point< T >::value >::type put_value(ptree &pt, T value)
ALMATH_API void check_version(const ptree &pt)
ALMATH_API ptree & require_actuatorcurve(ptree &pt, const std::string &actuator)
ALMATH_API int get_fps(const ptree &pt)
std::enable_if< std::is_floating_point< T >::value >::type check_cubic_bezier(int p0_frame, T, T p1_dframe, T, T p2_dframe, T, int p3_frame, T)
ALMATH_API ptree & require_key(ptree &pt, int frame)
std::enable_if< std::is_floating_point< T >::value >::type put_abscissa(ptree &pt, T abscissa)
BinaryOperation adjacent_for_each(InputIt first, InputIt last, BinaryOperation binary_op)
ALMATH_API void check_all(const ptree &pt)
ALMATH_API std::string get_value(const ptree &pt)
std::enable_if< std::is_floating_point< T >::value, T >::type get_ordinate(const ptree &pt)
ALMATH_API bool is_actuatorcurve(const ptree::value_type &val)
ALMATH_API void put_side(ptree &pt, Side side)
ALMATH_API void put_unit(ptree &pt, Unit unit)
auto get_labels(const ptree &pt) -> boost::select_second_const_range< decltype(boost::adaptors::filter(pt, Label::is_label))>
std::enable_if< std::is_floating_point< Scalar >::value >::type check_cubic_bezier(const ptree &pt)
ALMATH_API optional< const ptree & > get_tangent_optional(const ptree &pt, Side side)
ALMATH_API ptree & require_animation(ptree &root)
ALMATH_API void put_fps(ptree &pt, int fps)
std::enable_if< std::is_floating_point< T >::value, T >::type get_value(const ptree &pt)
ALMATH_API ptree & get_animation(ptree &root)
ALMATH_API bool is_key(const ptree::value_type &val)
auto get_actuatorcurves(const ptree &pt) -> boost::select_second_const_range< decltype(boost::adaptors::filter(pt, ActuatorCurve::is_actuatorcurve))>
ALMATH_API void put_actuator(ptree &pt, const std::string &name)
ALMATH_API void put_frame(ptree &pt, int frame)
const ptree & get_tangent(const ptree &pt, Side side)
boost::property_tree::ptree ptree
const ptree & get_key(const ptree &pt, int frame)
ALMATH_API Side get_side(const ptree &pt)
std::enable_if< std::is_floating_point< T >::value >::type put_ordinate(ptree &pt, T ordinate)
ALMATH_API void put_mute(ptree &pt, bool mute)
ALMATH_API int get_frame(const ptree &pt)
ALMATH_API ptree & require_tangent(ptree &pt, Side side)
ALMATH_API bool is_labels(const ptree::value_type &val)
ALMATH_API Unit get_unit(const ptree &pt)
std::enable_if< std::is_floating_point< T >::value, T >::type get_abscissa(const ptree &pt)
ALMATH_API ptree & add_labels(ptree &pt)
ALMATH_API optional< const ptree & > get_key_optional(const ptree &pt, int frame)
auto get_keys(const ptree &pt) -> boost::select_second_const_range< decltype(boost::adaptors::filter(pt, Key::is_key))>