Panda3D
animInterface.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file animInterface.I
10  * @author drose
11  * @date 2005-09-20
12  */
13 
14 /**
15  * Runs the entire animation from beginning to end and stops.
16  */
17 INLINE void AnimInterface::
18 play() {
19  play(0, get_num_frames() - 1);
20 }
21 
22 /**
23  * Runs the animation from the frame "from" to and including the frame "to",
24  * at which point the animation is stopped. Both "from" and "to" frame
25  * numbers may be outside the range (0, get_num_frames()) and the animation
26  * will follow the range correctly, reporting numbers modulo get_num_frames().
27  * For instance, play(0, get_num_frames() * 2) will play the animation twice
28  * and then stop.
29  */
30 INLINE void AnimInterface::
31 play(double from, double to) {
32  {
33  CDWriter cdata(_cycler);
34  cdata->play(from, to);
35  }
36  animation_activated();
37 }
38 
39 /**
40  * Starts the entire animation looping. If restart is true, the animation is
41  * restarted from the beginning; otherwise, it continues from the current
42  * frame.
43  */
44 INLINE void AnimInterface::
45 loop(bool restart) {
46  loop(restart, 0, get_num_frames() - 1);
47 }
48 
49 /**
50  * Loops the animation from the frame "from" to and including the frame "to",
51  * indefinitely. If restart is true, the animation is restarted from the
52  * beginning; otherwise, it continues from the current frame.
53  */
54 INLINE void AnimInterface::
55 loop(bool restart, double from, double to) {
56  {
57  CDWriter cdata(_cycler);
58  cdata->loop(restart, from, to);
59  }
60  animation_activated();
61 }
62 
63 /**
64  * Starts the entire animation bouncing back and forth between its first frame
65  * and last frame. If restart is true, the animation is restarted from the
66  * beginning; otherwise, it continues from the current frame.
67  */
68 INLINE void AnimInterface::
69 pingpong(bool restart) {
70  pingpong(restart, 0, get_num_frames() - 1);
71 }
72 
73 /**
74  * Loops the animation from the frame "from" to and including the frame "to",
75  * and then back in the opposite direction, indefinitely.
76  */
77 INLINE void AnimInterface::
78 pingpong(bool restart, double from, double to) {
79  {
80  CDWriter cdata(_cycler);
81  cdata->pingpong(restart, from, to);
82  }
83  animation_activated();
84 }
85 
86 /**
87  * Stops a currently playing or looping animation right where it is. The
88  * animation remains posed at the current frame.
89  */
90 INLINE void AnimInterface::
91 stop() {
92  CDWriter cdata(_cycler);
93  cdata->pose(cdata->get_full_fframe());
94 
95  // Don't call animation_activated() here; stopping an animation should not
96  // activate it.
97 }
98 
99 /**
100  * Sets the animation to the indicated frame and holds it there.
101  */
102 INLINE void AnimInterface::
103 pose(double frame) {
104  {
105  CDWriter cdata(_cycler);
106  cdata->pose(frame);
107  }
108  animation_activated();
109 }
110 
111 /**
112  * Changes the rate at which the animation plays. 1.0 is the normal speed,
113  * 2.0 is twice normal speed, and 0.5 is half normal speed. 0.0 is legal to
114  * pause the animation, and a negative value will play the animation
115  * backwards.
116  */
117 INLINE void AnimInterface::
118 set_play_rate(double play_rate) {
119  CDWriter cdata(_cycler);
120  cdata->internal_set_rate(cdata->_frame_rate, play_rate);
121 }
122 
123 /**
124  * Returns the rate at which the animation plays. See set_play_rate().
125  */
126 INLINE double AnimInterface::
127 get_play_rate() const {
128  CDReader cdata(_cycler);
129  return cdata->_play_rate;
130 }
131 
132 /**
133  * Returns the native frame rate of the animation. This is the number of
134  * frames per second that will elapse when the play_rate is set to 1.0. It is
135  * a fixed property of the animation and may not be adjusted by the user.
136  */
137 INLINE double AnimInterface::
138 get_frame_rate() const {
139  CDReader cdata(_cycler);
140  return cdata->_frame_rate;
141 }
142 
143 /**
144  * Returns the current integer frame number. This number will be in the range
145  * 0 <= f < get_num_frames().
146  */
147 INLINE int AnimInterface::
148 get_frame() const {
149  int num_frames = get_num_frames();
150  if (num_frames <= 0) {
151  return 0;
152  }
153  CDReader cdata(_cycler);
154  return cmod(cdata->get_full_frame(0), num_frames);
155 }
156 
157 /**
158  * Returns the current integer frame number + 1, constrained to the range 0 <=
159  * f < get_num_frames().
160  *
161  * If the play mode is PM_play, this will clamp to the same value as
162  * get_frame() at the end of the animation. If the play mode is any other
163  * value, this will wrap around to frame 0 at the end of the animation.
164  */
165 INLINE int AnimInterface::
166 get_next_frame() const {
167  int num_frames = get_num_frames();
168  if (num_frames <= 0) {
169  return 0;
170  }
171  CDReader cdata(_cycler);
172  return cmod(cdata->get_full_frame(1), num_frames);
173 }
174 
175 /**
176  * Returns the fractional part of the current frame. Normally, this is in the
177  * range 0.0 <= f < 1.0, but in the one special case of an animation playing
178  * to its end frame and stopping, it might exactly equal 1.0.
179  *
180  * It will always be true that get_full_frame() + get_frac() ==
181  * get_full_fframe().
182  */
183 INLINE double AnimInterface::
184 get_frac() const {
185  CDReader cdata(_cycler);
186  return cdata->get_frac();
187 }
188 
189 /**
190  * Returns the current integer frame number.
191  *
192  * Unlike the value returned by get_frame(), this frame number may extend
193  * beyond the range of get_num_frames() if the frame range passed to play(),
194  * loop(), etc. did.
195  *
196  * Unlike the value returned by get_full_fframe(), this return value will
197  * never exceed the value passed to to_frame in the play() method.
198  */
199 INLINE int AnimInterface::
200 get_full_frame() const {
201  CDReader cdata(_cycler);
202  return cdata->get_full_frame(0);
203 }
204 
205 /**
206  * Returns the current floating-point frame number.
207  *
208  * Unlike the value returned by get_frame(), this frame number may extend
209  * beyond the range of get_num_frames() if the frame range passed to play(),
210  * loop(), etc. did.
211  *
212  * Unlike the value returned by get_full_frame(), this return value may equal
213  * (to_frame + 1.0), when the animation has played to its natural end.
214  * However, in this case the return value of get_full_frame() will be
215  * to_frame, not (to_frame + 1).
216  */
217 INLINE double AnimInterface::
218 get_full_fframe() const {
219  CDReader cdata(_cycler);
220  return cdata->get_full_fframe();
221 }
222 
223 /**
224  * Returns true if the animation is currently playing, false if it is stopped
225  * (e.g. because stop() or pose() was called, or because it reached the end
226  * of the animation after play() was called).
227  */
228 INLINE bool AnimInterface::
229 is_playing() const {
230  CDReader cdata(_cycler);
231  return cdata->is_playing();
232 }
233 
234 /**
235  * Should be called by a derived class to specify the native frame rate of the
236  * animation. It is legal to call this after the animation has already
237  * started.
238  */
239 INLINE void AnimInterface::
240 set_frame_rate(double frame_rate) {
241  CDWriter cdata(_cycler);
242  cdata->internal_set_rate(frame_rate, cdata->_play_rate);
243 }
244 
245 /**
246  * Should be called by a derived class to specify the number of frames of the
247  * animation. It is legal to call this after the animation has already
248  * started, but doing so may suddenly change the apparent current frame
249  * number.
250  */
251 INLINE void AnimInterface::
252 set_num_frames(int num_frames) {
253  _num_frames = num_frames;
254 }
255 
256 /**
257  * Returns the fractional part of the current frame. Normally, this is in the
258  * range 0.0 <= f < 1.0, but in the one special case of an animation playing
259  * to its end frame and stopping, it might exactly equal 1.0.
260  *
261  * It will always be true that get_full_frame() + get_frac() ==
262  * get_full_fframe().
263  */
264 INLINE double AnimInterface::CData::
265 get_frac() const {
266  return get_full_fframe() - (double)get_full_frame(0);
267 }
268 
269 INLINE std::ostream &
270 operator << (std::ostream &out, const AnimInterface &ai) {
271  ai.output(out);
272  return out;
273 }
float cmod(float x, float y)
This is similar to fmod(), but it behaves properly when x is negative: that is, it always returns a v...
Definition: cmath.I:130
void loop(bool restart)
Starts the entire animation looping.
Definition: animInterface.I:45
void pingpong(bool restart)
Starts the entire animation bouncing back and forth between its first frame and last frame.
Definition: animInterface.I:69
void stop()
Stops a currently playing or looping animation right where it is.
Definition: animInterface.I:91
This is the fundamental interface for things that have a play/loop/stop type interface for frame-base...
Definition: animInterface.h:35
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
get_num_frames
Returns the number of frames in the animation.
Definition: animInterface.h:68
void pose(double frame)
Sets the animation to the indicated frame and holds it there.
void play()
Runs the entire animation from beginning to end and stops.
Definition: animInterface.I:18
set_play_rate
Changes the rate at which the animation plays.
Definition: animInterface.h:66