]>
Dogcows Code - chaz/yoink/blob - src/animation.cc
2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
32 #include "serializable.hh"
33 #include "mippleton.hh"
34 #include "animation.hh"
41 * The collection of nested animation classes. The animation implementation
42 * consists of an animation_impl classes which is allocated and initialized with
43 * the interface object. This class contains the specific fields which are
44 * required to run a single instance of an animation. The sequence data is
45 * loaded in a difference class which can be shared amongst multiple animation
46 * implementation instances.
49 struct animation::animation_impl
53 * Contains "global" animation data for the various animations which get
54 * loaded. This is a mippleton, so it will be shared amongst any animation
55 * which wants to use these loaded sequences.
58 struct animation_data
: public mippleton
<animation_data
>
61 * A frame of an animation sequence. A frame is merely an index which
62 * presumably represents a "slide" or tile which should be displayed,
63 * and the duration that is how long the slide will be shown.
68 unsigned index
; ///< Frame index.
69 scalar duration
; ///< Frame duration.
72 * Construction is initialization. The frame data is loaded from a
73 * frame map which is probably loaded within an animation file.
76 frame(serializable_ptr root
) :
80 std::map
<std::string
,serializable_ptr
> rootObj
;
82 if (root
->get(rootObj
))
84 std::map
<std::string
,serializable_ptr
>::iterator i
;
85 for (i
= rootObj
.begin(); i
!= rootObj
.end(); i
++)
87 std::string key
= (*i
).first
;
91 (*i
).second
->get(value
);
92 index
= unsigned(value
);
94 else if (key
== "duration")
97 (*i
).second
->getNumber(value
);
98 duration
= scalar(value
);
107 * A sequence is just a few attributes and a list of frames in the order
108 * that they should be played.
113 std::vector
<frame
> frames
; ///< List of frames.
114 scalar delay
; ///< Scale frame durations.
115 bool loop
; ///< Does the sequence repeat?
116 std::string next
; ///< Next sequence name.
119 * Construction is initialization. The constructor loads sequence
120 * data from the sequence map, presumably loaded from an animation
121 * file. The rest of the loading takes place in the frame's
122 * constructor which loads each individual frame.
125 sequence(serializable_ptr root
) :
129 std::map
<std::string
,serializable_ptr
> rootObj
;
131 if (root
->get(rootObj
))
133 std::map
<std::string
,serializable_ptr
>::iterator i
;
134 for (i
= rootObj
.begin(); i
!= rootObj
.end(); i
++)
136 std::string key
= (*i
).first
;
140 std::vector
<serializable_ptr
> framesObj
;
142 if ((*i
).second
->get(framesObj
))
144 std::vector
<serializable_ptr
>::iterator j
;
146 for (j
= framesObj
.begin();
147 j
!= framesObj
.end(); j
++)
151 frames
.push_back(frame(*j
));
156 else if (key
== "delay")
159 (*i
).second
->getNumber(value
);
160 delay
= scalar(value
);
162 else if (key
== "loop")
164 (*i
).second
->get(loop
);
166 else if (key
== "next")
168 (*i
).second
->get(next
);
177 * Starts loading a file with animation data. Such a file is formatted
178 * as a map of named sequences. The sequence constructor loads each
179 * individual sequence.
184 std::string filePath
= animation::getPathToResource(getName());
186 deserializer
in(filePath
);
188 serializable_ptr root
= in
.deserialize();
192 std::map
<std::string
,serializable_ptr
> rootObj
;
194 if (root
->get(rootObj
))
196 std::map
<std::string
,serializable_ptr
>::iterator i
;
198 for (i
= rootObj
.begin(); i
!= rootObj
.end(); i
++)
200 sequences
.insert(std::pair
<std::string
,sequence
>((*i
).first
,
201 sequence((*i
).second
)));
208 * Construction is initialization. The animation class data container
209 * registers itself as a mippleton and then loads the animation data.
212 explicit animation_data(const std::string
& name
) :
213 mippleton
<animation_data
>(name
)
218 std::map
<std::string
,sequence
> sequences
; ///< List of sequences.
223 * Construction is intialization.
226 animation_impl(const std::string
& name
) :
227 data(animation_data::retain(name
), &animation_data::release
),
236 * Sets up the animation classes to "play" a named sequence. If another
237 * sequence was active, it will be replaced as the current sequence. Future
238 * updates will progress the new sequence.
241 void startSequence(const std::string
& sequenceName
)
243 std::map
<std::string
,animation_data::sequence
>::iterator i
;
245 i
= data
->sequences
.find(sequenceName
);
247 if (i
!= data
->sequences
.end())
249 currentSequence
= &(*i
).second
;
251 frameIndex
= currentSequence
->frames
[0].index
;
253 frameDuration
= currentSequence
->delay
*
254 currentSequence
->frames
[0].duration
;
259 * Updates or progresses the animation sequence. If the time interval
260 * surpasses the duration of the current frame, a new frame becomes the
261 * current frame. If the last frame of a sequence expires, the active
262 * sequence will switch automatically to the designated "next" sequence, or
263 * if none is specified but the sequence is set to loop, the first frame of
264 * the sequence will become the current frame, and the animation essentially
268 void update(scalar t
, scalar dt
)
274 if (timeAccum
>= frameDuration
)
276 if (++frameCounter
>= currentSequence
->frames
.size())
278 if (!currentSequence
->next
.empty())
280 startSequence(currentSequence
->next
);
282 else if (currentSequence
->loop
)
293 frameIndex
= currentSequence
->frames
[frameCounter
].index
;
294 timeAccum
= frameDuration
- timeAccum
;
295 frameDuration
= currentSequence
->delay
*
296 currentSequence
->frames
[frameCounter
].duration
;
301 boost::shared_ptr
<animation_data
> data
; ///< Internal data.
303 animation_data::sequence
* currentSequence
; ///< Active sequence.
304 unsigned frameCounter
; ///< Current frame.
305 unsigned frameIndex
; ///< Index of current frame.
306 scalar timeAccum
; ///< Time accumulation.
307 scalar frameDuration
; ///< Scaled frame duration.
311 animation::animation(const std::string
& name
) :
313 impl(new animation::animation_impl(name
)) {}
316 void animation::startSequence(const std::string
& sequenceName
)
319 impl
->startSequence(sequenceName
);
322 void animation::update(scalar t
, scalar dt
)
330 * Gets the index for the current frame. This is presumably called by some
331 * drawing code which will draw the correct current frame.
334 unsigned animation::getFrame() const
336 return impl
->frameIndex
;
341 * Specialized search location for animation files. They can be found in the
342 * "animations" subdirectory of any of the searched directories.
345 std::string
animation::getPathToResource(const std::string
& name
)
347 return resource::getPathToResource("animations/" + name
+ ".json");
353 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.050021 seconds and 5 git commands to generate.