cgv
Loading...
Searching...
No Matches
animate.h
1#pragma once
2
3// make sure this is the first thing the compiler sees, while preventing warnings if
4// it happened to already be defined by something else including this header
5#ifndef _USE_MATH_DEFINES
6 #define _USE_MATH_DEFINES 1
7#endif
8#include <cmath>
9#include <limits>
10#include <cgv/data/ref_ptr.h>
11#include <cgv/base/base.h>
12#include <cgv/math/geom.h>
13#include <cgv/gui/trigger.h>
14
15#include "lib_begin.h"
16
17namespace cgv {
18 namespace gui {
19
20 class CGV_API animation;
21
22 typedef cgv::data::ref_ptr<animation, true> animation_ptr;
23
24 enum AnimationParameterMapping
25 {
26 APM_LINEAR = -3,
27 APM_SIN_SQUARED = -2,
28 APM_CUBIC = -1,
29 };
30
31 class CGV_API animation : public cgv::data::ref_counted
32 {
33 protected:
34 AnimationParameterMapping parameter_mapping;
35 double start_time;
36 double end_time;
38 virtual void set_value(double time) = 0;
39 public:
40 animation(double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_LINEAR);
41 virtual ~animation() {}
42 void set_base_ptr(cgv::base::base_ptr _bp);
43 void configure(AnimationParameterMapping _parameter_mapping, cgv::base::base_ptr _bp);
44 void set_parameter_mapping(AnimationParameterMapping _parameter_mapping);
45 double get_start_time() const;
46 bool has_started(double time) const;
47 bool is_over(double time) const;
48 double get_parameter(double time) const;
49 bool animates(const void* ptr) const;
50 bool overlaps(const char* value_ptr, size_t value_size) const;
51 virtual char* get_ptr() const = 0;
52 virtual size_t get_value_size() const = 0;
53 bool set_time(double time);
54 };
55
56 extern CGV_API void add_animation(animation_ptr a_ptr, bool terminate_other_animations = true);
57
58 template <typename T>
60 {
61 protected:
62 T start_value;
63 public:
64 T end_value;
65 protected:
66 T* value_ptr;
67 char* get_ptr() const { return reinterpret_cast<char*>(value_ptr); }
68 size_t get_value_size() const { return sizeof(T); }
69 public:
70 value_animation(T& value, const T& _end_value, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_SIN_SQUARED) :
71 animation(_start_time, _end_time, _parameter_mapping), value_ptr(&value), start_value(value), end_value(_end_value)
72 {}
73 };
74
75 template <typename T>
77 {
78 protected:
79 void set_value(double time) {
80 double lambda = this->get_parameter(time);
81 *this->value_ptr = (T)(1.0 - lambda)*this->start_value + (T)lambda*this->end_value;
82 }
83 public:
84 linear_blend_animation(T& value, const T& _end_value, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_SIN_SQUARED) :
85 value_animation<T>(value, _end_value, _start_time, _end_time, _parameter_mapping)
86 {}
87 };
88
89 template <typename T>
91 {
92 protected:
93 void set_value(double time) {
94 double lambda = this->get_parameter(time);
95 *this->value_ptr = pow(this->start_value,(1.0 - lambda))*pow(this->end_value, lambda);
96 }
97 public:
98 geometric_blend_animation(T& value, const T& _end_value, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_SIN_SQUARED) :
99 value_animation<T>(value, _end_value, _start_time, _end_time, _parameter_mapping)
100 {}
101 };
102
103 template <typename T>
105 {
106 double Omega;
107 protected:
108 void set_value(double time) {
109 double lambda = this->get_parameter(time);
110 *this->value_ptr = pow(this->start_value, (1.0 - lambda))*pow(this->end_value, lambda);
111 }
112 public:
113 slerp_animation(T& value, const T& _end_value, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_LINEAR) :
114 value_animation<T>(value, _end_value, _start_time, _end_time, _parameter_mapping)
115 {
116 Omega = acos(dot(this->start_value, this->end_value) / sqrt(dot(this->start_value,this->start_value)*dot(this->end_value,this->end_value)));
117 }
118 };
119
120
121 template <typename T>
122 class rotation_animation : public value_animation<cgv::math::fvec<T,3> >
123 {
124 public:
126 T angle;
127 protected:
128 void set_value(double time) {
129 double lambda = this->get_parameter(time);
130 *this->value_ptr = cgv::math::rotate(this->start_value, axis, lambda * angle);
131 }
132 public:
133 rotation_animation(cgv::math::fvec<T, 3>& value, const cgv::math::fvec<T, 3>& _axis, double _angle, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_SIN_SQUARED) :
134 value_animation<cgv::math::fvec<T, 3> >(value, rotate(value, _axis, _angle), _start_time, _end_time, _parameter_mapping), axis(_axis), angle(_angle)
135 {}
136 rotation_animation(cgv::math::fvec<T, 3>& value, const cgv::math::fvec<T, 3>& _end_value, double _start_time, double _end_time, AnimationParameterMapping _parameter_mapping = APM_SIN_SQUARED) :
137 value_animation<cgv::math::fvec<T, 3> >(value, _end_value, _start_time, _end_time, _parameter_mapping)
138 {
139 compute_rotation_axis_and_angle_from_vector_pair(this->start_value, this->end_value, axis, angle);
140 }
141 };
142
143
144 template <typename T>
145 animation_ptr animate_with_linear_blend(T& value, const T& target_value, double duration_sec, double delay_sec = 0.0f, bool terminate_other_animations = true)
146 {
147 double time = trigger::get_current_time();
148 animation_ptr a_ptr(new linear_blend_animation<T>(value, target_value, time + delay_sec, time + duration_sec + delay_sec));
149 add_animation(a_ptr, terminate_other_animations);
150 return a_ptr;
151 }
152
153 template <typename T>
154 animation_ptr animate_with_geometric_blend(T& value, const T& target_value, double duration_sec, double delay_sec = 0.0f, bool terminate_other_animations = true)
155 {
156 double time = trigger::get_current_time();
157 animation_ptr a_ptr(new geometric_blend_animation<T>(value, target_value, time + delay_sec, time + duration_sec + delay_sec));
158 add_animation(a_ptr, terminate_other_animations);
159 return a_ptr;
160 }
161
162 template <typename T>
163 animation_ptr animate_with_slerp(T& value, const T& target_value, double duration_sec, double delay_sec = 0.0f, bool terminate_other_animations = true)
164 {
165 double time = trigger::get_current_time();
166 animation_ptr a_ptr(new slerp_animation<T>(value, target_value, time + delay_sec, time + duration_sec + delay_sec));
167 add_animation(a_ptr, terminate_other_animations);
168 return a_ptr;
169 }
170 template <typename T>
171 animation_ptr animate_with_rotation(cgv::math::fvec<T, 3>& value, const cgv::math::fvec<T, 3>& target_value, double duration_sec, double delay_sec = 0.0f, bool terminate_other_animations = true)
172 {
173 double time = trigger::get_current_time();
174 animation_ptr a_ptr(new rotation_animation<T>(value, target_value, time + delay_sec, time + duration_sec + delay_sec));
175 add_animation(a_ptr, terminate_other_animations);
176 return a_ptr;
177 }
178 template <typename T>
179 animation_ptr animate_with_axis_rotation(cgv::math::fvec<T, 3>& value, const cgv::math::fvec<T, 3>& axis, T angle, double duration_sec, double delay_sec = 0.0f, bool terminate_other_animations = true)
180 {
181 double time = trigger::get_current_time();
182 animation_ptr a_ptr(new rotation_animation<T>(value, axis, angle, time + delay_sec, time + duration_sec + delay_sec));
183 add_animation(a_ptr, terminate_other_animations);
184 return a_ptr;
185 }
186 }
187}
188
189#include <cgv/config/lib_end.h>
if you derive your class from this class, a ref_ptr will do reference counting in the inhereted ref_c...
Definition ref_counted.h:11
reference counted pointer, which can work together with types that are derived from ref_counted,...
Definition ref_ptr.h:160
static double get_current_time()
return the current time
Definition trigger.cxx:70
A vector with zero based index.
Definition fvec.h:26
the cgv namespace
Definition print.h:11