AnimationTarget.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. #include "Base.h"
  2. #include "AnimationTarget.h"
  3. #include "Animation.h"
  4. #include "Game.h"
  5. #include "Node.h"
  6. #define ANIMATION_TARGET_INDEFINITE_STR "INDEFINITE"
  7. namespace gameplay
  8. {
  9. AnimationTarget::AnimationTarget()
  10. : _targetType(SCALAR), _animationChannels(NULL)
  11. {
  12. }
  13. AnimationTarget::~AnimationTarget()
  14. {
  15. if (_animationChannels)
  16. {
  17. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  18. while (itr != _animationChannels->end())
  19. {
  20. Animation::Channel* channel = (*itr);
  21. GP_ASSERT(channel);
  22. GP_ASSERT(channel->_animation);
  23. channel->_animation->removeChannel(channel);
  24. SAFE_DELETE(channel);
  25. itr++;
  26. }
  27. _animationChannels->clear();
  28. SAFE_DELETE(_animationChannels);
  29. }
  30. }
  31. Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, Curve::InterpolationType type)
  32. {
  33. GP_ASSERT(type != Curve::BEZIER && type != Curve::HERMITE);
  34. GP_ASSERT(keyCount >= 1 && keyTimes && keyValues);
  35. Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, type);
  36. return animation;
  37. }
  38. Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
  39. {
  40. GP_ASSERT(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
  41. Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
  42. return animation;
  43. }
  44. Animation* AnimationTarget::createAnimation(const char* id, const char* url)
  45. {
  46. Properties* p = Properties::create(url);
  47. GP_ASSERT(p);
  48. Animation* animation = createAnimation(id, (strlen(p->getNamespace()) > 0) ? p : p->getNextNamespace());
  49. SAFE_DELETE(p);
  50. return animation;
  51. }
  52. Animation* AnimationTarget::createAnimationFromTo(const char* id, int propertyId, float* from, float* to, Curve::InterpolationType type, unsigned long duration)
  53. {
  54. GP_ASSERT(from);
  55. GP_ASSERT(to);
  56. const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId);
  57. GP_ASSERT(propertyComponentCount > 0);
  58. float* keyValues = new float[2 * propertyComponentCount];
  59. memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
  60. memcpy(keyValues + propertyComponentCount, to, sizeof(float) * propertyComponentCount);
  61. unsigned int* keyTimes = new unsigned int[2];
  62. keyTimes[0] = 0;
  63. keyTimes[1] = (unsigned int)duration;
  64. Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
  65. SAFE_DELETE_ARRAY(keyValues);
  66. SAFE_DELETE_ARRAY(keyTimes);
  67. return animation;
  68. }
  69. Animation* AnimationTarget::createAnimationFromBy(const char* id, int propertyId, float* from, float* by, Curve::InterpolationType type, unsigned long duration)
  70. {
  71. GP_ASSERT(from);
  72. GP_ASSERT(by);
  73. const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId);
  74. GP_ASSERT(propertyComponentCount > 0);
  75. float* keyValues = new float[2 * propertyComponentCount];
  76. memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
  77. convertByValues(propertyId, propertyComponentCount, from, by);
  78. memcpy(keyValues + propertyComponentCount, by, sizeof(float) * propertyComponentCount);
  79. unsigned int* keyTimes = new unsigned int[2];
  80. keyTimes[0] = 0;
  81. keyTimes[1] = (unsigned int)duration;
  82. Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
  83. SAFE_DELETE_ARRAY(keyValues);
  84. SAFE_DELETE_ARRAY(keyTimes);
  85. return animation;
  86. }
  87. Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties)
  88. {
  89. GP_ASSERT(animationProperties);
  90. if (std::strcmp(animationProperties->getNamespace(), "animation") != 0)
  91. {
  92. GP_ERROR("Invalid animation namespace '%s'.", animationProperties->getNamespace());
  93. return NULL;
  94. }
  95. const char* propertyIdStr = animationProperties->getString("property");
  96. if (propertyIdStr == NULL)
  97. {
  98. GP_ERROR("Attribute 'property' must be specified for an animation.");
  99. return NULL;
  100. }
  101. // Get animation target property id
  102. int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr);
  103. if (propertyId == -1)
  104. {
  105. GP_ERROR("Property ID is invalid.");
  106. return NULL;
  107. }
  108. unsigned int keyCount = animationProperties->getInt("keyCount");
  109. if (keyCount == 0)
  110. {
  111. GP_ERROR("Attribute 'keyCount' must be specified for an animation.");
  112. return NULL;
  113. }
  114. const char* keyTimesStr = animationProperties->getString("keyTimes");
  115. if (keyTimesStr == NULL)
  116. {
  117. GP_ERROR("Attribute 'keyTimes' must be specified for an animation.");
  118. return NULL;
  119. }
  120. const char* keyValuesStr = animationProperties->getString("keyValues");
  121. if (keyValuesStr == NULL)
  122. {
  123. GP_ERROR("Attribute 'keyValues' must be specified for an animation.");
  124. return NULL;
  125. }
  126. const char* curveStr = animationProperties->getString("curve");
  127. if (curveStr == NULL)
  128. {
  129. GP_ERROR("Attribute 'curve' must be specified for an animation.");
  130. return NULL;
  131. }
  132. char delimeter = ' ';
  133. size_t startOffset = 0;
  134. size_t endOffset = std::string::npos;
  135. unsigned int* keyTimes = new unsigned int[keyCount];
  136. for (size_t i = 0; i < keyCount; i++)
  137. {
  138. endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset);
  139. if (endOffset != std::string::npos)
  140. {
  141. keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0);
  142. }
  143. else
  144. {
  145. keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0);
  146. }
  147. startOffset = endOffset + 1;
  148. }
  149. startOffset = 0;
  150. endOffset = std::string::npos;
  151. int componentCount = getAnimationPropertyComponentCount(propertyId);
  152. GP_ASSERT(componentCount > 0);
  153. unsigned int components = keyCount * componentCount;
  154. float* keyValues = new float[components];
  155. for (unsigned int i = 0; i < components; i++)
  156. {
  157. endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset);
  158. if (endOffset != std::string::npos)
  159. {
  160. keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str());
  161. }
  162. else
  163. {
  164. keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str());
  165. }
  166. startOffset = endOffset + 1;
  167. }
  168. const char* keyInStr = animationProperties->getString("keyIn");
  169. float* keyIn = NULL;
  170. if (keyInStr)
  171. {
  172. keyIn = new float[components];
  173. startOffset = 0;
  174. endOffset = std::string::npos;
  175. for (unsigned int i = 0; i < components; i++)
  176. {
  177. endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset);
  178. if (endOffset != std::string::npos)
  179. {
  180. keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str());
  181. }
  182. else
  183. {
  184. keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str());
  185. }
  186. startOffset = endOffset + 1;
  187. }
  188. }
  189. const char* keyOutStr = animationProperties->getString("keyOut");
  190. float* keyOut = NULL;
  191. if (keyOutStr)
  192. {
  193. keyOut = new float[components];
  194. startOffset = 0;
  195. endOffset = std::string::npos;
  196. for (unsigned int i = 0; i < components; i++)
  197. {
  198. endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset);
  199. if (endOffset != std::string::npos)
  200. {
  201. keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str());
  202. }
  203. else
  204. {
  205. keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str());
  206. }
  207. startOffset = endOffset + 1;
  208. }
  209. }
  210. int curve = Curve::getInterpolationType(curveStr);
  211. Animation* animation = NULL;
  212. if (keyIn && keyOut)
  213. {
  214. animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve);
  215. }
  216. else
  217. {
  218. animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
  219. }
  220. const char* repeat = animationProperties->getString("repeatCount");
  221. if (repeat)
  222. {
  223. if (strcmp(repeat, ANIMATION_TARGET_INDEFINITE_STR) == 0)
  224. {
  225. animation->getClip()->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
  226. }
  227. else
  228. {
  229. float value;
  230. sscanf(repeat, "%f", &value);
  231. animation->getClip()->setRepeatCount(value);
  232. }
  233. }
  234. SAFE_DELETE_ARRAY(keyOut);
  235. SAFE_DELETE_ARRAY(keyIn);
  236. SAFE_DELETE_ARRAY(keyValues);
  237. SAFE_DELETE_ARRAY(keyTimes);
  238. Properties* pClip = animationProperties->getNextNamespace();
  239. if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
  240. {
  241. int frameCount = animationProperties->getInt("frameCount");
  242. if (frameCount <= 0)
  243. {
  244. GP_ERROR("Frame count must be greater than zero for a clip.");
  245. return animation;
  246. }
  247. animation->createClips(animationProperties, (unsigned int) frameCount);
  248. }
  249. return animation;
  250. }
  251. void AnimationTarget::destroyAnimation(const char* id)
  252. {
  253. // Find the animation with the specified ID.
  254. Animation::Channel* channel = getChannel(id);
  255. if (channel == NULL)
  256. return;
  257. // Remove this target's channel from animation, and from the target's list of channels.
  258. GP_ASSERT(channel->_animation);
  259. channel->_animation->removeChannel(channel);
  260. removeChannel(channel);
  261. SAFE_DELETE(channel);
  262. }
  263. Animation* AnimationTarget::getAnimation(const char* id) const
  264. {
  265. if (_animationChannels)
  266. {
  267. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  268. GP_ASSERT(*itr);
  269. if (id == NULL)
  270. return (*itr)->_animation;
  271. Animation::Channel* channel = NULL;
  272. for (; itr != _animationChannels->end(); itr++)
  273. {
  274. channel = (Animation::Channel*)(*itr);
  275. GP_ASSERT(channel);
  276. GP_ASSERT(channel->_animation);
  277. if (channel->_animation->_id.compare(id) == 0)
  278. {
  279. return channel->_animation;
  280. }
  281. }
  282. }
  283. return NULL;
  284. }
  285. int AnimationTarget::getPropertyId(TargetType type, const char* propertyIdStr)
  286. {
  287. GP_ASSERT(propertyIdStr);
  288. if (type == AnimationTarget::TRANSFORM)
  289. {
  290. if (strcmp(propertyIdStr, "ANIMATE_SCALE") == 0)
  291. {
  292. return Transform::ANIMATE_SCALE;
  293. }
  294. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_X") == 0)
  295. {
  296. return Transform::ANIMATE_SCALE_X;
  297. }
  298. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_Y") == 0)
  299. {
  300. return Transform::ANIMATE_SCALE_Y;
  301. }
  302. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_Z") == 0)
  303. {
  304. return Transform::ANIMATE_SCALE_Z;
  305. }
  306. else if (strcmp(propertyIdStr, "ANIMATE_ROTATE") == 0)
  307. {
  308. return Transform::ANIMATE_ROTATE;
  309. }
  310. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE") == 0)
  311. {
  312. return Transform::ANIMATE_TRANSLATE;
  313. }
  314. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_X") == 0)
  315. {
  316. return Transform::ANIMATE_TRANSLATE_X;
  317. }
  318. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_Y") == 0)
  319. {
  320. return Transform::ANIMATE_TRANSLATE_Y;
  321. }
  322. else if (strcmp(propertyIdStr, "ANIMATE_TRANSLATE_Z") == 0)
  323. {
  324. return Transform::ANIMATE_TRANSLATE_Z;
  325. }
  326. else if (strcmp(propertyIdStr, "ANIMATE_ROTATE_TRANSLATE") == 0)
  327. {
  328. return Transform::ANIMATE_ROTATE_TRANSLATE;
  329. }
  330. else if (strcmp(propertyIdStr, "ANIMATE_SCALE_ROTATE_TRANSLATE") == 0)
  331. {
  332. return Transform::ANIMATE_SCALE_ROTATE_TRANSLATE;
  333. }
  334. }
  335. else
  336. {
  337. if (strcmp(propertyIdStr, "ANIMATE_UNIFORM") == 0)
  338. {
  339. return MaterialParameter::ANIMATE_UNIFORM;
  340. }
  341. }
  342. return -1;
  343. }
  344. void AnimationTarget::addChannel(Animation::Channel* channel)
  345. {
  346. if (_animationChannels == NULL)
  347. _animationChannels = new std::vector<Animation::Channel*>;
  348. GP_ASSERT(channel);
  349. _animationChannels->push_back(channel);
  350. }
  351. void AnimationTarget::removeChannel(Animation::Channel* channel)
  352. {
  353. if (_animationChannels)
  354. {
  355. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  356. for ( ; itr != _animationChannels->end(); itr++)
  357. {
  358. Animation::Channel* temp = *itr;
  359. if (channel == temp)
  360. {
  361. _animationChannels->erase(itr);
  362. if (_animationChannels->empty())
  363. SAFE_DELETE(_animationChannels);
  364. return;
  365. }
  366. }
  367. }
  368. }
  369. Animation::Channel* AnimationTarget::getChannel(const char* id) const
  370. {
  371. if (_animationChannels)
  372. {
  373. std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
  374. if (id == NULL)
  375. return (*itr);
  376. Animation::Channel* channel = NULL;
  377. for (; itr != _animationChannels->end(); itr++)
  378. {
  379. channel = (Animation::Channel*)(*itr);
  380. GP_ASSERT(channel);
  381. if (channel->_animation->_id.compare(id) == 0)
  382. {
  383. return channel;
  384. }
  385. }
  386. }
  387. return NULL;
  388. }
  389. void AnimationTarget::cloneInto(AnimationTarget* target, NodeCloneContext &context) const
  390. {
  391. if (_animationChannels)
  392. {
  393. for (std::vector<Animation::Channel*>::const_iterator it = _animationChannels->begin(); it != _animationChannels->end(); ++it)
  394. {
  395. Animation::Channel* channel = *it;
  396. GP_ASSERT(channel);
  397. GP_ASSERT(channel->_animation);
  398. Animation* animation = context.findClonedAnimation(channel->_animation);
  399. if (animation != NULL)
  400. {
  401. Animation::Channel* channelCopy = new Animation::Channel(*channel, animation, target);
  402. animation->addChannel(channelCopy);
  403. }
  404. else
  405. {
  406. // Clone the animation and register it with the context so that it only gets cloned once.
  407. animation = channel->_animation->clone(channel, target);
  408. context.registerClonedAnimation(channel->_animation, animation);
  409. }
  410. }
  411. }
  412. }
  413. void AnimationTarget::convertByValues(unsigned int propertyId, unsigned int componentCount, float* from, float* by)
  414. {
  415. if (_targetType == AnimationTarget::TRANSFORM)
  416. {
  417. switch(propertyId)
  418. {
  419. case Transform::ANIMATE_SCALE:
  420. case Transform::ANIMATE_SCALE_UNIT:
  421. case Transform::ANIMATE_SCALE_X:
  422. case Transform::ANIMATE_SCALE_Y:
  423. case Transform::ANIMATE_SCALE_Z:
  424. {
  425. convertScaleByValues(from, by, componentCount);
  426. break;
  427. }
  428. case Transform::ANIMATE_TRANSLATE:
  429. case Transform::ANIMATE_TRANSLATE_X:
  430. case Transform::ANIMATE_TRANSLATE_Y:
  431. case Transform::ANIMATE_TRANSLATE_Z:
  432. {
  433. convertByValues(from, by, componentCount);
  434. break;
  435. }
  436. case Transform::ANIMATE_ROTATE:
  437. {
  438. convertQuaternionByValues(from, by);
  439. break;
  440. }
  441. case Transform::ANIMATE_ROTATE_TRANSLATE:
  442. {
  443. convertQuaternionByValues(from, by);
  444. convertByValues(from + 4, by + 4, 3);
  445. break;
  446. }
  447. case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
  448. {
  449. convertScaleByValues(from, by, 3);
  450. convertQuaternionByValues(from + 3, by + 3);
  451. convertByValues(from + 7, by + 7, 3);
  452. break;
  453. }
  454. }
  455. }
  456. else
  457. {
  458. convertByValues(from, by, componentCount);
  459. }
  460. }
  461. void AnimationTarget::convertQuaternionByValues(float* from, float* by)
  462. {
  463. Quaternion qFrom(from);
  464. Quaternion qBy(by);
  465. qBy.multiply(qFrom);
  466. memcpy(by, (float*)&qBy, sizeof(float) * 4);
  467. }
  468. void AnimationTarget::convertScaleByValues(float* from, float* by, unsigned int componentCount)
  469. {
  470. for (unsigned int i = 0; i < componentCount; i++)
  471. {
  472. by[i] *= from[i];
  473. }
  474. }
  475. void AnimationTarget::convertByValues(float* from, float* by, unsigned int componentCount)
  476. {
  477. for (unsigned int i = 0; i < componentCount; i++)
  478. {
  479. by[i] += from[i];
  480. }
  481. }
  482. }