DAEUtil.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. #include <set>
  2. #include "Base.h"
  3. #include "DAEUtil.h"
  4. #include "StringUtil.h"
  5. namespace gameplay
  6. {
  7. /**
  8. * Returns the index of the skeleton in skeletonArray that points to the given node.
  9. *
  10. * @param skeletonArray The array of skeletons to search.
  11. * @param node The target node.
  12. *
  13. * @return The index in skeletonArray or -1 if not found.
  14. */
  15. static int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, const domNodeRef& node);
  16. /**
  17. * Gets all of the animation channels that target the given node and appends them to the list.
  18. *
  19. * @param animationRef The animation to search in.
  20. * @param nodeIdSlash The node's id with a forward slash appended to it.
  21. * @param channels The list of channels to append to.
  22. */
  23. static void getAnimationChannels(const domAnimationRef& animationRef, const std::string& nodeIdSlash, std::list<domChannelRef>& channels);
  24. void getAnimationChannels(const domNodeRef& node, std::list<domChannelRef>& channels)
  25. {
  26. assert(node->getId());
  27. std::string nodeIdSlash (node->getId());
  28. nodeIdSlash.append("/");
  29. domCOLLADA* root = (domCOLLADA*)node->getDocument()->getDomRoot();
  30. domLibrary_animations_Array& animationLibrary = root->getLibrary_animations_array();
  31. size_t animationLibraryCount = animationLibrary.getCount();
  32. for (size_t i = 0; i < animationLibraryCount; ++i)
  33. {
  34. domLibrary_animationsRef& animationsRef = animationLibrary.get(i);
  35. domAnimation_Array& animationArray = animationsRef->getAnimation_array();
  36. size_t animationCount = animationArray.getCount();
  37. for (size_t j = 0; j < animationCount; ++j)
  38. {
  39. domAnimationRef& animationRef = animationArray.get(j);
  40. getAnimationChannels(animationRef, nodeIdSlash, channels);
  41. }
  42. }
  43. // Recursively do the same for all nodes
  44. daeTArray< daeSmartRef<daeElement> > children;
  45. node->getChildren(children);
  46. size_t childCount = children.getCount();
  47. for (size_t i = 0; i < childCount; ++i)
  48. {
  49. daeElementRef childElement = children[i];
  50. if (childElement->typeID() == domNode::ID())
  51. {
  52. domNodeRef childNode = daeSafeCast<domNode>(childElement);
  53. getAnimationChannels(childNode, channels);
  54. }
  55. }
  56. }
  57. void getJointNames(const domSourceRef source, std::vector<std::string>& list)
  58. {
  59. // BLENDER used name_array
  60. const domName_arrayRef& nameArray = source->getName_array();
  61. if (nameArray.cast())
  62. {
  63. domListOfNames& ids = nameArray->getValue();
  64. size_t jointCount = (size_t)nameArray->getCount();
  65. for (size_t j = 0; j < jointCount; ++j)
  66. {
  67. list.push_back(std::string(ids.get(j)));
  68. }
  69. }
  70. else
  71. {
  72. // Seymour used IDREF_array
  73. const domIDREF_arrayRef& idArray = source->getIDREF_array();
  74. if (idArray.cast())
  75. {
  76. xsIDREFS& ids = idArray->getValue();
  77. size_t jointCount = (size_t)idArray->getCount();
  78. for (size_t j = 0; j < jointCount; ++j)
  79. {
  80. list.push_back(std::string(ids.get(j).getID()));
  81. }
  82. }
  83. }
  84. }
  85. void getJointNames(const domSkin* skin, std::vector<std::string>& list)
  86. {
  87. const domSkin::domJointsRef& joints = skin->getJoints();
  88. const domInputLocal_Array& inputArray = joints->getInput_array();
  89. size_t inputCount = inputArray.getCount();
  90. for (size_t i = 0; i < inputCount; ++i)
  91. {
  92. const domInputLocalRef input = inputArray.get(i);
  93. const char* semantic = input->getSemantic();
  94. if (strcmp(semantic, "JOINT") == 0)
  95. {
  96. daeElement* sourceElement = input->getSource().getElement();
  97. if (sourceElement)
  98. {
  99. const domSourceRef source = daeSafeCast<domSource>(sourceElement);
  100. getJointNames(source, list);
  101. }
  102. }
  103. }
  104. }
  105. domSource* getInputSource(const domChannelRef& channel)
  106. {
  107. daeElement* element = channel->getSource().getElement();
  108. if (element && element->typeID() == domSampler::ID())
  109. {
  110. domSampler* sampler = daeSafeCast<domSampler>(element);
  111. const domInputLocal_Array& inputArray = sampler->getInput_array();
  112. size_t inputArrayCount = inputArray.getCount();
  113. for (size_t i = 0; i < inputArrayCount; ++i)
  114. {
  115. const domInputLocalRef& input = inputArray.get(i);
  116. if (strcmp(input->getSemantic(), "INPUT") == 0)
  117. {
  118. daeElement* e = input->getSource().getElement();
  119. if (e && e->typeID() == domSource::ID())
  120. {
  121. domSource* source = daeSafeCast<domSource>(e);
  122. assert(source);
  123. return source;
  124. }
  125. }
  126. }
  127. }
  128. return NULL;
  129. }
  130. const domSamplerRef getSampler(const domChannelRef& channel)
  131. {
  132. const domURIFragmentType& uri = channel->getSource();
  133. daeElementRef element = uri.getElement();
  134. if (element && element->typeID() == domSampler::ID())
  135. {
  136. const domSamplerRef sampler = daeSafeCast<domSampler>(element);
  137. return sampler;
  138. }
  139. // resolve the source manually by searching for the sampler in the animation that the channel is a child of.
  140. const std::string& id = uri.id();
  141. const daeElementRef& parent = channel->getParent();
  142. if (parent && parent->typeID() == domAnimation::ID())
  143. {
  144. const domAnimationRef animation = daeSafeCast<domAnimation>(parent);
  145. const domSampler_Array& samplerArray = animation->getSampler_array();
  146. size_t count = samplerArray.getCount();
  147. for (size_t i = 0; i < count; ++i)
  148. {
  149. const domSamplerRef& sampler = samplerArray.get(i);
  150. if (id.compare(sampler->getId()) == 0)
  151. {
  152. return sampler;
  153. }
  154. }
  155. }
  156. return NULL;
  157. }
  158. const domSourceRef getSource(const domInputLocalRef& inputLocal, const domAnimationRef& animation)
  159. {
  160. const domURIFragmentType& uri = inputLocal->getSource();
  161. daeElementRef element = uri.getElement();
  162. if (element && element->typeID() == domSampler::ID())
  163. {
  164. const domSourceRef source = daeSafeCast<domSource>(element);
  165. return source;
  166. }
  167. // Resolve the URI by searching through the animation's list of sources
  168. const std::string& id = uri.id();
  169. const domSource_Array& sourceArray = animation->getSource_array();
  170. size_t count = sourceArray.getCount();
  171. for (size_t i = 0; i < count; ++i)
  172. {
  173. const domSourceRef source = sourceArray.get(i);
  174. if (id.compare(source->getId()) == 0)
  175. {
  176. return source;
  177. }
  178. }
  179. return NULL;
  180. }
  181. const domName_arrayRef getSourceNameArray(const domSourceRef& source)
  182. {
  183. const domName_arrayRef& nameArray = source->getName_array();
  184. if (nameArray)
  185. {
  186. return nameArray;
  187. }
  188. daeTArray<daeSmartRef<daeElement> > children;
  189. source->getChildren(children);
  190. size_t childCount = children.getCount();
  191. for (size_t i = 0; i < childCount; ++i)
  192. {
  193. const daeElementRef element = children.get(i);
  194. if (element->typeID() == domName_array::ID())
  195. {
  196. return daeSafeCast<domName_array>(element);
  197. }
  198. }
  199. return NULL;
  200. }
  201. const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_controllerRef& instanceController)
  202. {
  203. domInstance_controller::domSkeleton_Array& skeletonArray = instanceController->getSkeleton_array();
  204. size_t count = skeletonArray.getCount();
  205. if (count == 0)
  206. {
  207. return NULL;
  208. }
  209. if (count == 1)
  210. {
  211. return skeletonArray.get(0);
  212. }
  213. // Maya sometimes outputs multiple skeleton elements.
  214. // Find the skeleton element that points to the root most node.
  215. const domInstance_controller::domSkeletonRef& currentSkeleton = skeletonArray.get(0);
  216. const daeElementRef element = currentSkeleton->getValue().getElement();
  217. if (element && element->typeID() == domNode::ID())
  218. {
  219. domNode* node = daeSafeCast<domNode>(element);
  220. int index = 0;
  221. bool loop = true;
  222. do
  223. {
  224. daeElementRef parent = node->getParent();
  225. if (parent && parent->typeID() == domNode::ID())
  226. {
  227. domNodeRef parentNode = daeSafeCast<domNode>(parent);
  228. int result = getIndex(skeletonArray, parentNode);
  229. if (result >= 0)
  230. {
  231. index = result;
  232. }
  233. node = parentNode;
  234. }
  235. else
  236. {
  237. loop = false;
  238. }
  239. } while (loop);
  240. if (index >= 0)
  241. {
  242. return skeletonArray.get(index);
  243. }
  244. }
  245. return NULL;
  246. }
  247. domNode* getRootJointNode(const domSkin* skin)
  248. {
  249. std::vector<std::string> names;
  250. getJointNames(skin, names);
  251. daeSIDResolver resolver(const_cast<domSkin*>(skin)->getDocument()->getDomRoot(), names[0].c_str());
  252. daeElement* element = resolver.getElement();
  253. if (element && element->typeID() == domNode::ID())
  254. {
  255. domNode* node = daeSafeCast<domNode>(resolver.getElement());
  256. return node;
  257. }
  258. return NULL;
  259. }
  260. bool equalKeyTimes(const domSource* s1, const domSource* s2)
  261. {
  262. // TODO: shouldn't assume that the source has a float array.
  263. const domFloat_arrayRef& f1 = s1->getFloat_array();
  264. const domFloat_arrayRef& f2 = s2->getFloat_array();
  265. if (f1->getCount() == f2->getCount())
  266. {
  267. const domListOfFloats& list1 = f1->getValue();
  268. const domListOfFloats& list2 = f2->getValue();
  269. size_t count = (size_t)f1->getCount();
  270. for (size_t i = 0; i < count; ++i)
  271. {
  272. if (list1.get(i) != list2.get(i))
  273. {
  274. return false;
  275. }
  276. }
  277. return true;
  278. }
  279. return false;
  280. }
  281. bool equalKeyTimes(const domChannelRef& c1, const domChannelRef& c2)
  282. {
  283. domSource* s1 = getInputSource(c1);
  284. domSource* s2 = getInputSource(c2);
  285. assert(s1);
  286. assert(s2);
  287. return equalKeyTimes(s1, s2);
  288. }
  289. void moveChannelAndSouresToAnimation(domChannelRef& channel, domAnimationRef& animation)
  290. {
  291. assert(channel);
  292. assert(animation);
  293. daeElement::removeFromParent(channel);
  294. animation->add(channel); // move channel
  295. daeElementRef element = channel->getSource().getElement();
  296. if (element)
  297. {
  298. domSamplerRef sampler = daeSafeCast<domSampler>(element);
  299. domInputLocal_Array& inputArray = sampler->getInput_array();
  300. size_t inputArrayCount = inputArray.getCount();
  301. for (size_t i = 0; i < inputArrayCount; ++i)
  302. {
  303. inputArray = sampler->getInput_array();
  304. const domInputLocalRef& input = inputArray.get(i);
  305. daeElementRef element = input->getSource().getElement();
  306. if (element && element->typeID() == domSource::ID())
  307. {
  308. domSourceRef source = daeSafeCast<domSource>(element);
  309. assert(source);
  310. daeElement::removeFromParent(source);
  311. animation->add(source); // move source
  312. }
  313. }
  314. daeElement::removeFromParent(sampler);
  315. animation->add(sampler); // move sampler
  316. }
  317. }
  318. bool isEmptyAnimation(domAnimationRef& animation)
  319. {
  320. return animation->getAnimation_array().getCount() == 0 &&
  321. animation->getChannel_array().getCount() == 0 &&
  322. animation->getSampler_array().getCount() == 0 &&
  323. animation->getSource_array().getCount() == 0;
  324. }
  325. int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, const domNodeRef& node)
  326. {
  327. const std::string nodeId = node->getId();
  328. size_t count = skeletonArray.getCount();
  329. for (size_t i = 0; i < count; ++i)
  330. {
  331. const domInstance_controller::domSkeletonRef& skeleton = skeletonArray.get(i);
  332. daeElementRef element = skeleton->getValue().getElement();
  333. if (element->typeID() == domNode::ID())
  334. {
  335. domNodeRef targetNode = daeSafeCast<domNode>(element);
  336. if (nodeId.compare(targetNode->getId()) == 0)
  337. {
  338. return i;
  339. }
  340. }
  341. }
  342. return -1;
  343. }
  344. void getAnimationChannels(const domAnimationRef& animationRef, const std::string& nodeIdSlash, std::list<domChannelRef>& channels)
  345. {
  346. domChannel_Array& channelArray = animationRef->getChannel_array();
  347. size_t channelArrayCount = channelArray.getCount();
  348. for (size_t k = 0; k < channelArrayCount; ++k)
  349. {
  350. domChannelRef& channel = channelArray.get(k);
  351. const char* target = channel->getTarget();
  352. // TODO: Assumes only one target per channel?
  353. if (startsWith(target, nodeIdSlash.c_str()))
  354. {
  355. channels.push_back(channel);
  356. }
  357. }
  358. // This animation could have child animations.
  359. const domAnimation_Array& animationArray = animationRef->getAnimation_array();
  360. unsigned int animationCount = animationArray.getCount();
  361. for (size_t i = 0; i < animationCount; ++i)
  362. {
  363. getAnimationChannels(animationArray[i], nodeIdSlash, channels);
  364. }
  365. }
  366. domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
  367. {
  368. daeElement* scene = domScene->getInstance_visual_scene()->getUrl().getElement();
  369. if (scene->typeID() == domVisual_scene::ID())
  370. {
  371. return static_cast<domVisual_scene*>(scene);
  372. }
  373. // DAE_FBX sometimes doesn't export an ID. In that case, see if there is only one visual scene and use that.
  374. // Most of the time there is only one visual scene.
  375. domCOLLADA* root = (domCOLLADA*)domScene->getDocument()->getDomRoot();
  376. domLibrary_visual_scenes_Array& visualSceneLibrary = root->getLibrary_visual_scenes_array();
  377. size_t visualSceneLibraryCount = visualSceneLibrary.getCount();
  378. for (size_t i = 0; i < visualSceneLibraryCount; ++i)
  379. {
  380. domLibrary_visual_scenesRef scenesRef = visualSceneLibrary.get(i);
  381. domVisual_scene_Array visualScenes = scenesRef->getVisual_scene_array();
  382. size_t visualSceneCount = visualScenes.getCount();
  383. for (size_t j = 0; j < visualSceneCount; ++j)
  384. {
  385. domVisual_sceneRef visualScene = visualScenes.get(j);
  386. if (domVisual_scene* v = visualScene.cast())
  387. {
  388. return v;
  389. }
  390. }
  391. }
  392. return NULL;
  393. }
  394. domNode* getParent(domNodeRef node)
  395. {
  396. daeElement* parent = node->getParent();
  397. if (parent && parent->typeID() == domNode::ID())
  398. {
  399. domNodeRef parentNode = daeSafeCast<domNode>(parent);
  400. return parentNode.cast();
  401. }
  402. return NULL;
  403. }
  404. domAnimation* getAnimation(domChannelRef channel)
  405. {
  406. daeElement* parent = channel->getParent();
  407. if (parent && parent->typeID() == domAnimation::ID())
  408. {
  409. domAnimationRef parentNode = daeSafeCast<domAnimation>(parent);
  410. return parentNode.cast();
  411. }
  412. return NULL;
  413. }
  414. domNode* getCommonNodeAncestor(std::list<domNodeRef>& nodes)
  415. {
  416. if (nodes.empty())
  417. return NULL;
  418. if (nodes.size() == 1)
  419. return nodes.begin()->cast();
  420. std::list<domNode*> ancestors;
  421. size_t minAncestorCount = INT_MAX;
  422. for (std::list<domNodeRef>::iterator it = nodes.begin(); it != nodes.end(); ++it)
  423. {
  424. domNodeRef& node = *it;
  425. getNodeAncestors(node, ancestors);
  426. ancestors.push_back(node.cast());
  427. minAncestorCount = std::min(minAncestorCount, ancestors.size());
  428. }
  429. ancestors.resize(minAncestorCount);
  430. return ancestors.back();
  431. }
  432. void getNodeAncestors(domNodeRef& node, std::list<domNode*>& ancestors)
  433. {
  434. ancestors.clear();
  435. domNode* parent = getParent(node);
  436. while (parent != NULL)
  437. {
  438. ancestors.push_front(parent);
  439. parent = getParent(parent);
  440. }
  441. }
  442. bool findGroupAnimationNodes(domCOLLADA* dom, std::vector<std::string>& nodesToGroup)
  443. {
  444. bool groupPossible = false;
  445. const domLibrary_controllers_Array& controllersArrays = dom->getLibrary_controllers_array();
  446. size_t controllersArraysCount = controllersArrays.getCount();
  447. for (size_t i = 0; i < controllersArraysCount; ++i)
  448. {
  449. const domLibrary_controllersRef& libraryController = controllersArrays.get(i);
  450. const domController_Array& controllerArray = libraryController->getController_array();
  451. size_t controllerCount = controllerArray.getCount();
  452. for (size_t j = 0; j < controllerCount; ++j)
  453. {
  454. const domControllerRef& controllerRef = controllerArray.get(j);
  455. const domSkinRef& skinRef = controllerRef->getSkin();
  456. if (skinRef.cast() != NULL)
  457. {
  458. domSkin::domJointsRef joints = skinRef->getJoints();
  459. domInputLocal_Array& jointInputs = joints->getInput_array();
  460. for (unsigned int i = 0; i < jointInputs.getCount(); ++i)
  461. {
  462. domInputLocalRef input = jointInputs.get(i);
  463. std::string inputSemantic = std::string(input->getSemantic());
  464. domURIFragmentType* sourceURI = &input->getSource();
  465. sourceURI->resolveElement();
  466. const domSourceRef source = (domSource*)(daeElement*)sourceURI->getElement();
  467. if (equals(inputSemantic, "JOINT"))
  468. {
  469. std::list<domChannelRef> channels;
  470. std::list<domNodeRef> nodes;
  471. findChannelsTargetingJoints(source, channels, nodes);
  472. // If the channels don't share the same animation then they can be grouped.
  473. if (!sameAnimation(channels))
  474. {
  475. groupPossible = true;
  476. domNode* parentMost = getCommonNodeAncestor(nodes);
  477. nodesToGroup.push_back(parentMost->getId());
  478. }
  479. }
  480. }
  481. }
  482. }
  483. }
  484. return groupPossible;
  485. }
  486. bool sameAnimation(std::list<domChannelRef>& channels)
  487. {
  488. std::list<domChannelRef>::iterator it = channels.begin();
  489. domAnimation* temp = getAnimation(*it);
  490. ++it;
  491. for (; it != channels.end(); ++it)
  492. {
  493. if (getAnimation(*it) != temp)
  494. return false;
  495. }
  496. return true;
  497. }
  498. void findChannelsTargetingJoints(const domSourceRef& source, std::list<domChannelRef>& channels, std::list<domNodeRef>& nodes)
  499. {
  500. std::vector<std::string> jointNames;
  501. getJointNames(source, jointNames);
  502. for (std::vector<std::string>::iterator i = jointNames.begin(); i != jointNames.end(); ++i)
  503. {
  504. daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
  505. daeElement* element = resolver.getElement();
  506. if (element && element->typeID() == domNode::ID())
  507. {
  508. domNodeRef node = daeSafeCast<domNode>(element);
  509. nodes.push_back(node);
  510. getAnimationChannels(node, channels);
  511. }
  512. }
  513. }
  514. }