1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3 
4 This file is part of Aquaria.
5 
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21 #ifndef SKELETALSPRITE_H
22 #define SKELETALSPRITE_H
23 
24 #include "Quad.h"
25 #include "SimpleIStringStream.h"
26 // for 2d system only
27 
28 enum AnimationCommand
29 {
30 	AC_PRT_LOAD		=0,
31 	AC_PRT_START		,
32 	AC_PRT_STOP			,
33 	AC_SEGS_START		,
34 	AC_FRM_SHOW			,
35 	AC_SND_PLAY			,
36 	AC_SEGS_STOP
37 };
38 
39 class ParticleEffect;
40 class SkeletalSprite;
41 
42 class Bone : public Quad
43 {
44 public:
45 	Bone();
46 	void setAnimated(int a);
47 
48 	enum {
49 		ANIM_NONE		= 0,
50 		ANIM_POS		= 1,
51 		ANIM_ROT		= 2,
52 		ANIM_ALL		= 10
53 	};
54 	void createStrip(bool vert, int num);
55 	Quad* addFrame(const std::string &gfx);
56 	void showFrame(int i);
57 	void destroy();
58 	std::string gfx;
59 	std::string name;
60 	int boneIdx, pidx, rbp;
61 	std::map<int, ParticleEffect*> emitters;
62 	std::string prt;
63 	std::vector<Vector> changeStrip;
64 
65 	bool generateCollisionMask;
66 	int animated;
67 	Vector originalScale;
68 
69 	void addSegment(Bone *b);
70 
71 	int segmentChain;
72 
73 	void updateSegments();
74 	void updateSegment(Bone *b, const Vector &diff);
75 
76 	SkeletalSprite *skeleton;
77 
78 
79 	void setSegmentProps(int minDist, int maxDist, bool reverse);
80 	Vector segmentOffset;
81 
82 	bool fileRenderQuad;
83 
84 
85 protected:
86 	int minDist, maxDist, reverse;
87 	std::vector<Bone*> segments;
88 };
89 
90 class BoneCommand
91 {
92 public:
93 	void parse(Bone *b, SimpleIStringStream &is);
94 	void run();
95 	AnimationCommand command;
96 	Bone *b;
97 
98 	int slot;
99 	std::string file;
100 };
101 
102 class BoneKeyframe
103 {
104 public:
BoneKeyframe()105 	BoneKeyframe() : idx(0), x(0), y(0), rot(0), doScale(0), sx(1), sy(1) {}
106 	int idx, x, y, rot;
107 	float sx, sy;
108 	bool doScale;
109 	std::vector<Vector> strip;
110 };
111 
112 class SkeletalKeyframe
113 {
114 public:
SkeletalKeyframe()115 	SkeletalKeyframe()
116 	{
117 		lerpType = 0;
118 		t = 0;
119 	}
120 	int lerpType;
121 	float t;
122 	std::string sound;
123 	std::vector<BoneKeyframe> keyframes;
124 	BoneKeyframe *getBoneKeyframe(int idx);
125 	std::string cmd;
126 	std::vector<BoneCommand> commands;
127 
128 	void copyAllButTime(SkeletalKeyframe *copy);
129 };
130 
131 class Animation
132 {
133 public:
134 	std::string name;
135 	typedef std::vector <SkeletalKeyframe> Keyframes;
136 	Keyframes keyframes;
137 	SkeletalKeyframe *getKeyframe(int key);
138 	SkeletalKeyframe *getLastKeyframe();
139 	SkeletalKeyframe *getFirstKeyframe();
140 	SkeletalKeyframe *getPrevKeyframe(float t);
141 	SkeletalKeyframe *getNextKeyframe(float t);
142 	void cloneKey(int key, float toffset);
143 	void deleteKey(int key);
144 	void reorderKeyframes();
145 	float getAnimationLength();
146 	int getSkeletalKeyframeIndex(SkeletalKeyframe *skey);
147 	int getNumKeyframes();
148 	void reverse();
149 };
150 
151 class SkeletalSprite;
152 
153 class AnimationLayer
154 {
155 public:
156 
157 	//----
158 	AnimationLayer();
159 	void setSkeletalSprite(SkeletalSprite *s);
160 	Animation *getCurrentAnimation();
161 	void animate(const std::string &animation, int loop);
162 	void update(float dt);
163 	void updateBones();
164 	void stopAnimation();
165 	float getAnimationLength();
166 	bool createTransitionAnimation(const std::string& anim, float time);
167 	void playAnimation(int idx, int loop);
168 	void playCurrentAnimation(int loop);
169 	void enqueueAnimation(const std::string& anim, int loop);
170 	float transitionAnimate(std::string anim, float time, int loop);
171 	void setTimeMultiplier(float t);
172 	bool isAnimating();
173 	//float lerp(float v1, float v2, float dt, int lerpType);
174 
175 	//----
176 	float fallThru;
177 	float fallThruSpeed;
178 	std::string name;
179 	std::vector<int> ignoreBones;
180 	std::vector<int> includeBones;
181 	SkeletalSprite *s;
182 
183 	SkeletalKeyframe *lastNewKey;
184 	//int index;
185 	float timer;
186 	int loop;
187 	Animation blendAnimation;
188 	std::string enqueuedAnimation;
189 	int enqueuedAnimationLoop;
190 	//float timeMultiplier;
191 	//HACK: should be a lerped float
192 	InterpolatedVector timeMultiplier;
193 	float animationLength;
194 	int currentAnimation;
195 	bool animating;
196 
197 
198 };
199 
200 class SkeletalSprite : public RenderObject
201 {
202 public:
203 
204 	SkeletalSprite();
205 	void loadSkeletal(const std::string &fn);
206 	bool saveSkeletal(const std::string &fn);
207 	void loadSkin(const std::string &fn);
208 
209 	Bone *getBoneByIdx(int idx);
210 	Bone *getBoneByName(const std::string &name);
211 	void animate(const std::string &animation, int loop = 0, int layer=0);
212 
213 
214 
215 	void setTime(float time, int layer=0);
216 
217 	void updateBones();
218 	void playCurrentAnimation(int loop=0, int layer=0);
219 	void stopAnimation(int layer=0);
220 	void stopAllAnimations();
221 
222 	float transitionAnimate(const std::string& anim, float time, int loop=0, int layer=0);
223 
224 	bool isAnimating(int layer=0);
225 
226 	void setTimeMultiplier(float t, int layer=0);
227 
228 	Bone* getSelectedBone(bool mouseBased = true);
229 	Animation *getCurrentAnimation(int layer=0);
230 
231 
232 	void nextAnimation();
233 	void prevAnimation();
234 	void lastAnimation();
235 	void firstAnimation();
236 	void updateSelectedBoneColor();
237 
238 
239 	void setFreeze(bool f);
240 
241 
242 
243 	Animation *getAnimation(const std::string& anim);
244 
245 	std::vector<Animation> animations;
246 	std::vector<Bone*> bones;
247 
getSelectedBoneIdx(void)248 	inline int getSelectedBoneIdx(void) { return selectedBone; }
249 	void setSelectedBone(int b);
250 	void selectPrevBone();
251 	void selectNextBone();
252 
253 	bool isLoaded();
getNumAnimLayers()254 	int getNumAnimLayers() const { return animLayers.size(); }
255 
256 	AnimationLayer* getAnimationLayer(int l);
257 	int getBoneIdx(Bone *b);
258 	void toggleBone(int idx, int v);
259 
260 	void setAnimationKeyNotify(RenderObject *r);
261 
262 	std::string filenameLoaded;
263 
264 	static std::string animationPath, skinPath, secondaryAnimationPath;
265 	static void clearCache();
266 
267 protected:
268 	bool frozen;
269 	RenderObject *animKeyNotify;
270 	bool loaded;
271 	int selectedBone;
272 	friend class AnimationLayer;
273 	std::vector<AnimationLayer> animLayers;
274 	Bone* initBone(int idx, std::string gfx, int pidx, int rbp=0, std::string name="", float cr=0, bool fh=false, bool fv=false, const Vector &cp=Vector(0,0,0));
275 	void deleteBones();
276 	void onUpdate(float dt);
277 };
278 
279 #endif
280