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