AnimationTarget.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. #include "Base.h"
  2. #include "AnimationTarget.h"
  3. #include "Animation.h"
  4. #include "Game.h"
  5. #include "Node.h"
  6. namespace gameplay
  7. {
  8. AnimationTarget::AnimationTarget()
  9. : _targetType(SCALAR), _animationChannels(NULL)
  10. {
  11. }
  12. AnimationTarget::~AnimationTarget()
  13. {
  14. if (_animationChannels)
  15. {
  16. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  17. while (itr != _animationChannels->end())
  18. {
  19. Animation::Channel* channel = (*itr);
  20. channel->_animation->removeChannel(channel);
  21. SAFE_DELETE(channel);
  22. itr++;
  23. }
  24. _animationChannels->clear();
  25. SAFE_DELETE(_animationChannels);
  26. }
  27. }
  28. Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
  29. {
  30. assert(type != Curve::BEZIER && type != Curve::HERMITE);
  31. assert(keyCount >= 1 && keyTimes && keyValues);
  32. Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, type);
  33. return animation;
  34. }
  35. Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
  36. {
  37. assert(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
  38. Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
  39. return animation;
  40. }
  41. Animation* AnimationTarget::createAnimation(const char* id, const char* url)
  42. {
  43. assert(url);
  44. Properties* p = Properties::create(url);
  45. assert(p);
  46. Animation* animation = createAnimation(id, (strlen(p->getNamespace()) > 0) ? p : p->getNextNamespace());
  47. SAFE_DELETE(p);
  48. return animation;
  49. }
  50. Animation* AnimationTarget::createAnimationFromTo(const char* id, int propertyId, float* from, float* to, Curve::InterpolationType type, unsigned long duration)
  51. {
  52. const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId);
  53. float* keyValues = new float[2 * propertyComponentCount];
  54. memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
  55. memcpy(keyValues + propertyComponentCount, to, sizeof(float) * propertyComponentCount);
  56. unsigned long* keyTimes = new unsigned long[2];
  57. keyTimes[0] = 0;
  58. keyTimes[1] = duration;
  59. Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
  60. SAFE_DELETE_ARRAY(keyValues);
  61. SAFE_DELETE_ARRAY(keyTimes);
  62. return animation;
  63. }
  64. Animation* AnimationTarget::createAnimationFromBy(const char* id, int propertyId, float* from, float* by, Curve::InterpolationType type, unsigned long duration)
  65. {
  66. const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId);
  67. float* keyValues = new float[2 * propertyComponentCount];
  68. memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
  69. memcpy(keyValues + propertyComponentCount, by, sizeof(float) * propertyComponentCount);
  70. unsigned long* keyTimes = new unsigned long[2];
  71. keyTimes[0] = 0;
  72. keyTimes[1] = duration;
  73. Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
  74. SAFE_DELETE_ARRAY(keyValues);
  75. SAFE_DELETE_ARRAY(keyTimes);
  76. return animation;
  77. }
  78. Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties)
  79. {
  80. assert(animationProperties);
  81. assert(std::strcmp(animationProperties->getNamespace(), "animation") == 0);
  82. const char* propertyIdStr = animationProperties->getString("property");
  83. assert(propertyIdStr);
  84. // Get animation target property id
  85. int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr);
  86. assert(propertyId != -1);
  87. unsigned int keyCount = animationProperties->getInt("keyCount");
  88. assert(keyCount > 0);
  89. const char* keyTimesStr = animationProperties->getString("keyTimes");
  90. assert(keyTimesStr);
  91. const char* keyValuesStr = animationProperties->getString("keyValues");
  92. assert(keyValuesStr);
  93. const char* curveStr = animationProperties->getString("curve");
  94. assert(curveStr);
  95. char delimeter = ' ';
  96. unsigned int startOffset = 0;
  97. unsigned int endOffset = (unsigned int)std::string::npos;
  98. unsigned long* keyTimes = new unsigned long[keyCount];
  99. for (unsigned int i = 0; i < keyCount; i++)
  100. {
  101. endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset);
  102. if (endOffset != std::string::npos)
  103. {
  104. keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0);
  105. }
  106. else
  107. {
  108. keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0);
  109. }
  110. startOffset = endOffset + 1;
  111. }
  112. startOffset = 0;
  113. endOffset = (unsigned int)std::string::npos;
  114. int componentCount = getAnimationPropertyComponentCount(propertyId);
  115. assert(componentCount > 0);
  116. unsigned int components = keyCount * componentCount;
  117. float* keyValues = new float[components];
  118. for (unsigned int i = 0; i < components; i++)
  119. {
  120. endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset);
  121. if (endOffset != std::string::npos)
  122. {
  123. keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str());
  124. }
  125. else
  126. {
  127. keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str());
  128. }
  129. startOffset = endOffset + 1;
  130. }
  131. const char* keyInStr = animationProperties->getString("keyIn");
  132. float* keyIn = NULL;
  133. if (keyInStr)
  134. {
  135. keyIn = new float[components];
  136. startOffset = 0;
  137. endOffset = (unsigned int)std::string::npos;
  138. for (unsigned int i = 0; i < components; i++)
  139. {
  140. endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset);
  141. if (endOffset != std::string::npos)
  142. {
  143. keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str());
  144. }
  145. else
  146. {
  147. keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str());
  148. }
  149. startOffset = endOffset + 1;
  150. }
  151. }
  152. const char* keyOutStr = animationProperties->getString("keyOut");
  153. float* keyOut = NULL;
  154. if (keyOutStr)
  155. {
  156. keyOut = new float[components];
  157. startOffset = 0;
  158. endOffset = (unsigned int)std::string::npos;
  159. for (unsigned int i = 0; i < components; i++)
  160. {
  161. endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset);
  162. if (endOffset != std::string::npos)
  163. {
  164. keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str());
  165. }
  166. else
  167. {
  168. keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str());
  169. }
  170. startOffset = endOffset + 1;
  171. }
  172. }
  173. int curve = Curve::getInterpolationType(curveStr);
  174. Animation* animation = NULL;
  175. if (keyIn && keyOut)
  176. {
  177. animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve);
  178. }
  179. else
  180. {
  181. animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
  182. }
  183. SAFE_DELETE(keyOut);
  184. SAFE_DELETE(keyIn);
  185. SAFE_DELETE(keyValues);
  186. SAFE_DELETE(keyTimes);
  187. Properties* pClip = animationProperties->getNextNamespace();
  188. if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
  189. {
  190. int frameCount = animationProperties->getInt("frameCount");
  191. assert(frameCount > 0);
  192. animation->createClips(animationProperties, (unsigned int) frameCount);
  193. }
  194. return animation;
  195. }
  196. void AnimationTarget::destroyAnimation(const char* id)
  197. {
  198. // Find the animation with the specified ID.
  199. Animation::Channel* channel = getChannel(id);
  200. if (channel == NULL)
  201. return;
  202. // Remove this target's channel from animation, and from the target's list of channels.
  203. channel->_animation->removeChannel(channel);
  204. removeChannel(channel);
  205. SAFE_DELETE(channel);
  206. }
  207. Animation* AnimationTarget::getAnimation(const char* id) const
  208. {
  209. if (_animationChannels)
  210. {
  211. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  212. if (id == NULL)
  213. return (*itr)->_animation;
  214. Animation::Channel* channel = NULL;
  215. for (; itr != _animationChannels->end(); itr++)
  216. {
  217. channel = (Animation::Channel*)(*itr);
  218. if (channel->_animation->_id.compare(id) == 0)
  219. {
  220. return channel->_animation;
  221. }
  222. }
  223. }
  224. return NULL;
  225. }
  226. int AnimationTarget::getPropertyId(TargetType type, const char* propertyIdStr)
  227. {
  228. if (type == AnimationTarget::TRANSFORM)
  229. {
  230. if (strcmp(propertyIdStr, "ANIMATE_SCALE") == 0)
  231. {
  232. return Transform::ANIMATE_SCALE;
  233. }
  234. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_X") == 0)
  235. {
  236. return Transform::ANIMATE_SCALE_X;
  237. }
  238. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_Y") == 0)
  239. {
  240. return Transform::ANIMATE_SCALE_Y;
  241. }
  242. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_Z") == 0)
  243. {
  244. return Transform::ANIMATE_SCALE_Z;
  245. }
  246. else if (strcmp(propertyIdStr, "ANIMATE_ROTATE") == 0)
  247. {
  248. return Transform::ANIMATE_ROTATE;
  249. }
  250. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE") == 0)
  251. {
  252. return Transform::ANIMATE_TRANSLATE;
  253. }
  254. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_X") == 0)
  255. {
  256. return Transform::ANIMATE_TRANSLATE_X;
  257. }
  258. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_Y") == 0)
  259. {
  260. return Transform::ANIMATE_TRANSLATE_Y;
  261. }
  262. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_Z") == 0)
  263. {
  264. return Transform::ANIMATE_TRANSLATE_Z;
  265. }
  266. else if (strcmp(propertyIdStr, "ANIMATE_ROTATE_TRANSLATE") == 0)
  267. {
  268. return Transform::ANIMATE_ROTATE_TRANSLATE;
  269. }
  270. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_ROTATE_TRANSLATE") == 0)
  271. {
  272. return Transform::ANIMATE_SCALE_ROTATE_TRANSLATE;
  273. }
  274. }
  275. else
  276. {
  277. if (strcmp(propertyIdStr, "ANIMATE_UNIFORM") == 0)
  278. {
  279. return MaterialParameter::ANIMATE_UNIFORM;
  280. }
  281. }
  282. return -1;
  283. }
  284. void AnimationTarget::addChannel(Animation::Channel* channel)
  285. {
  286. if (_animationChannels == NULL)
  287. _animationChannels = new std::vector<Animation::Channel*>;
  288. _animationChannels->push_back(channel);
  289. }
  290. void AnimationTarget::removeChannel(Animation::Channel* channel)
  291. {
  292. if (_animationChannels)
  293. {
  294. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  295. for ( ; itr != _animationChannels->end(); itr++)
  296. {
  297. Animation::Channel* temp = *itr;
  298. if (channel == temp)
  299. {
  300. _animationChannels->erase(itr);
  301. if (_animationChannels->empty())
  302. SAFE_DELETE(_animationChannels);
  303. return;
  304. }
  305. }
  306. }
  307. }
  308. Animation::Channel* AnimationTarget::getChannel(const char* id) const
  309. {
  310. if (_animationChannels)
  311. {
  312. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  313. if (id == NULL)
  314. return (*itr);
  315. Animation::Channel* channel = NULL;
  316. for (; itr != _animationChannels->end(); itr++)
  317. {
  318. channel = (Animation::Channel*)(*itr);
  319. if (channel->_animation->_id.compare(id) == 0)
  320. {
  321. return channel;
  322. }
  323. }
  324. }
  325. return NULL;
  326. }
  327. void AnimationTarget::cloneInto(AnimationTarget* target, NodeCloneContext &context) const
  328. {
  329. if (_animationChannels)
  330. {
  331. for (std::vector<Animation::Channel*>::const_iterator it = _animationChannels->begin(); it != _animationChannels->end(); ++it)
  332. {
  333. Animation::Channel* channel = *it;
  334. assert(channel->_animation);
  335. Animation* animation = context.findClonedAnimation(channel->_animation);
  336. if (animation != NULL)
  337. {
  338. Animation::Channel* channelCopy = new Animation::Channel(*channel, animation, target);
  339. animation->addChannel(channelCopy);
  340. }
  341. else
  342. {
  343. // Clone the animation and register it with the context so that it only gets cloned once.
  344. animation = channel->_animation->clone(channel, target);
  345. context.registerClonedAnimation(channel->_animation, animation);
  346. }
  347. }
  348. }
  349. }
  350. }