GPBFile.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. #include "Base.h"
  2. #include "GPBFile.h"
  3. #include "Transform.h"
  4. #include "StringUtil.h"
  5. #include "EncoderArguments.h"
  6. #include "Heightmap.h"
  7. #define EPSILON 1.2e-7f;
  8. namespace gameplay
  9. {
  10. static GPBFile* __instance = NULL;
  11. /**
  12. * Returns true if the given value is close to one.
  13. */
  14. static bool isAlmostOne(float value);
  15. /**
  16. * Gets the common node ancestor for the given list of nodes.
  17. * This function assumes that the nodes share a common ancestor.
  18. *
  19. * @param nodes The list of nodes.
  20. *
  21. * @return The common node ancestor or NULL if the list of was empty.
  22. */
  23. static Node* getCommonNodeAncestor(const std::vector<Node*>& nodes);
  24. /**
  25. * Gets the list of node ancestors for the given node.
  26. *
  27. * @param node The node to get the ancestors for.
  28. * @param ancestors The output list of ancestors.
  29. * The first element is the root node and the last element is the direct parent of the node.
  30. */
  31. static void getNodeAncestors(Node* node, std::list<Node*>& ancestors);
  32. GPBFile::GPBFile(void)
  33. : _file(NULL), _animationsAdded(false)
  34. {
  35. __instance = this;
  36. }
  37. GPBFile::~GPBFile(void)
  38. {
  39. }
  40. GPBFile* GPBFile::getInstance()
  41. {
  42. return __instance;
  43. }
  44. bool GPBFile::saveBinary(const std::string& filepath)
  45. {
  46. _file = fopen(filepath.c_str(), "w+b");
  47. if (!_file)
  48. {
  49. return false;
  50. }
  51. size_t n = 0;
  52. // identifier
  53. char identifier[] = { '«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n' };
  54. n = fwrite(identifier, 1, sizeof(identifier), _file);
  55. if (n != sizeof(identifier))
  56. {
  57. fclose(_file);
  58. return false;
  59. }
  60. // version
  61. n = fwrite(GPB_VERSION, 1, sizeof(GPB_VERSION), _file);
  62. if (n != sizeof(GPB_VERSION))
  63. {
  64. fclose(_file);
  65. return false;
  66. }
  67. // TODO: Check for errors on all file writing.
  68. // write refs
  69. _refTable.writeBinary(_file);
  70. // meshes
  71. write(_geometry.size(), _file);
  72. for (std::list<Mesh*>::const_iterator i = _geometry.begin(); i != _geometry.end(); ++i)
  73. {
  74. (*i)->writeBinary(_file);
  75. }
  76. // Objects
  77. write(_objects.size(), _file);
  78. for (std::list<Object*>::const_iterator i = _objects.begin(); i != _objects.end(); ++i)
  79. {
  80. (*i)->writeBinary(_file);
  81. }
  82. _refTable.updateOffsets(_file);
  83. fclose(_file);
  84. return true;
  85. }
  86. bool GPBFile::saveText(const std::string& filepath)
  87. {
  88. _file = fopen(filepath.c_str(), "w");
  89. if (!_file)
  90. {
  91. return false;
  92. }
  93. if (fprintf(_file, "<root>\n") <= 0)
  94. {
  95. fclose(_file);
  96. return false;
  97. }
  98. // TODO: Check for errors on all file writing.
  99. // write refs
  100. _refTable.writeText(_file);
  101. // meshes
  102. for (std::list<Mesh*>::const_iterator i = _geometry.begin(); i != _geometry.end(); ++i)
  103. {
  104. (*i)->writeText(_file);
  105. }
  106. // Objects
  107. for (std::list<Object*>::const_iterator i = _objects.begin(); i != _objects.end(); ++i)
  108. {
  109. (*i)->writeText(_file);
  110. }
  111. fprintf(_file, "</root>");
  112. fclose(_file);
  113. return true;
  114. }
  115. void GPBFile::add(Object* obj)
  116. {
  117. _objects.push_back(obj);
  118. }
  119. void GPBFile::addScene(Scene* scene)
  120. {
  121. addToRefTable(scene);
  122. _objects.push_back(scene);
  123. }
  124. void GPBFile::addCamera(Camera* camera)
  125. {
  126. addToRefTable(camera);
  127. _cameras.push_back(camera);
  128. }
  129. void GPBFile::addLight(Light* light)
  130. {
  131. addToRefTable(light);
  132. _lights.push_back(light);
  133. }
  134. void GPBFile::addMesh(Mesh* mesh)
  135. {
  136. addToRefTable(mesh);
  137. _geometry.push_back(mesh);
  138. }
  139. void GPBFile::addNode(Node* node)
  140. {
  141. addToRefTable(node);
  142. _nodes.push_back(node);
  143. }
  144. void GPBFile::addScenelessNode(Node* node)
  145. {
  146. addToRefTable(node);
  147. _nodes.push_back(node);
  148. // Nodes are normally written to file as part of a scene.
  149. // Nodes that don't belong to a scene need to be written on their own (outside a scene).
  150. // That is why node is added to the list of objects here.
  151. _objects.push_back(node);
  152. }
  153. void GPBFile::addAnimation(Animation* animation)
  154. {
  155. _animations.add(animation);
  156. if (!_animationsAdded)
  157. {
  158. // The animations container should only be added once and only if the file has at least one animation.
  159. _animationsAdded = true;
  160. addToRefTable(&_animations);
  161. add(&_animations);
  162. }
  163. }
  164. void GPBFile::addToRefTable(Object* obj)
  165. {
  166. if (obj)
  167. {
  168. const std::string& id = obj->getId();
  169. if (id.length() > 0)
  170. {
  171. if (_refTable.get(id) == NULL)
  172. {
  173. _refTable.add(id, obj);
  174. }
  175. }
  176. }
  177. }
  178. Object* GPBFile::getFromRefTable(const std::string& id)
  179. {
  180. return _refTable.get(id);
  181. }
  182. bool GPBFile::idExists(const std::string& id)
  183. {
  184. return _refTable.get(id) != NULL;
  185. }
  186. Camera* GPBFile::getCamera(const char* id)
  187. {
  188. if (!id)
  189. return NULL;
  190. // TODO: O(n) search is not ideal
  191. for (std::list<Camera*>::const_iterator i = _cameras.begin(); i != _cameras.end(); ++i)
  192. {
  193. const std::string& _id = (*i)->getId();
  194. if (_id.length() > 0 && strncmp(id, _id.c_str(), 255) == 0)
  195. {
  196. return *i;
  197. }
  198. }
  199. return NULL;
  200. }
  201. Light* GPBFile::getLight(const char* id)
  202. {
  203. if (!id)
  204. return NULL;
  205. // TODO: O(n) search is not ideal
  206. for (std::list<Light*>::const_iterator i = _lights.begin(); i != _lights.end(); ++i)
  207. {
  208. const std::string& _id = (*i)->getId();
  209. if (_id.length() > 0 && strncmp(id, _id.c_str(), 255) == 0)
  210. {
  211. return *i;
  212. }
  213. }
  214. return NULL;
  215. }
  216. Mesh* GPBFile::getMesh(const char* id)
  217. {
  218. if (!id)
  219. return NULL;
  220. // TODO: O(n) search is not ideal
  221. for (std::list<Mesh*>::const_iterator i = _geometry.begin(); i != _geometry.end(); ++i)
  222. {
  223. const std::string& _id = (*i)->getId();
  224. if (_id.length() > 0 && strncmp(id, _id.c_str(), 255) == 0)
  225. {
  226. return *i;
  227. }
  228. }
  229. return NULL;
  230. }
  231. Node* GPBFile::getNode(const char* id)
  232. {
  233. if (!id)
  234. return NULL;
  235. // TODO: O(n) search is not ideal
  236. for (std::list<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i)
  237. {
  238. const std::string& _id = (*i)->getId();
  239. if (_id.length() > 0 && strncmp(id, _id.c_str(), 255) == 0)
  240. {
  241. return *i;
  242. }
  243. }
  244. return NULL;
  245. }
  246. Animations* GPBFile::getAnimations()
  247. {
  248. return &_animations;
  249. }
  250. void GPBFile::adjust()
  251. {
  252. // calculate the ambient color for each scene
  253. for (std::list<Object*>::iterator i = _objects.begin(); i != _objects.end(); ++i)
  254. {
  255. Object* obj = *i;
  256. if (obj->getTypeId() == Object::SCENE_ID)
  257. {
  258. Scene* scene = dynamic_cast<Scene*>(obj);
  259. scene->calcAmbientColor();
  260. }
  261. }
  262. for (std::list<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i)
  263. {
  264. computeBounds(*i);
  265. }
  266. // try to convert joint transform animations into rotation animations
  267. //optimizeTransformAnimations();
  268. // TODO:
  269. // remove ambient _lights
  270. // for each node
  271. // if node has ambient light
  272. // if node has no camera, mesh or children but 1 ambient light
  273. // delete node and remove from ref table
  274. // delete light and remove from ref table
  275. //
  276. // merge animations if possible
  277. // Search for animations that have the same target and key times and see if they can be merged.
  278. // Blender will output a simple translation animation to 3 separate animations with the same key times but targeting X, Y and Z.
  279. // This can be merged into one animation. Same for scale animations.
  280. // Generate heightmaps
  281. const std::vector<EncoderArguments::HeightmapOption>& heightmaps = EncoderArguments::getInstance()->getHeightmapOptions();
  282. for (unsigned int i = 0, count = heightmaps.size(); i < count; ++i)
  283. {
  284. Heightmap::generate(heightmaps[i].nodeIds, heightmaps[i].filename.c_str(), heightmaps[i].isHighPrecision);
  285. }
  286. }
  287. void GPBFile::groupMeshSkinAnimations()
  288. {
  289. for (std::list<Node*>::iterator it = _nodes.begin(); it != _nodes.end(); ++it)
  290. {
  291. if (Model* model = (*it)->getModel())
  292. {
  293. if (MeshSkin* skin = model->getSkin())
  294. {
  295. const std::vector<Node*>& joints = skin->getJoints();
  296. Node* commonAncestor = getCommonNodeAncestor(joints);
  297. if (commonAncestor)
  298. {
  299. // group the animation channels that target this common ancestor and its child nodes
  300. Animation* animation = new Animation();
  301. animation->setId("animations");
  302. moveAnimationChannels(commonAncestor, animation);
  303. _animations.add(animation);
  304. }
  305. }
  306. }
  307. }
  308. }
  309. void GPBFile::renameAnimations(std::vector<std::string>& animationIds, const char* newId)
  310. {
  311. const unsigned int animationCount = _animations.getAnimationCount();
  312. for (unsigned int animationIndex = 0; animationIndex < animationCount; ++animationIndex)
  313. {
  314. Animation* animation = _animations.getAnimation(animationIndex);
  315. assert(animation);
  316. std::vector<std::string>::const_iterator it = find(animationIds.begin(), animationIds.end(), animation->getId());
  317. if (it != animationIds.end())
  318. {
  319. animation->setId(newId);
  320. }
  321. }
  322. }
  323. void GPBFile::computeBounds(Node* node)
  324. {
  325. assert(node);
  326. if (Model* model = node->getModel())
  327. {
  328. if (Mesh* mesh = model->getMesh())
  329. {
  330. mesh->computeBounds();
  331. }
  332. }
  333. }
  334. void GPBFile::optimizeTransformAnimations()
  335. {
  336. const unsigned int animationCount = _animations.getAnimationCount();
  337. for (unsigned int animationIndex = 0; animationIndex < animationCount; ++animationIndex)
  338. {
  339. Animation* animation = _animations.getAnimation(animationIndex);
  340. assert(animation);
  341. const int channelCount = animation->getAnimationChannelCount();
  342. // loop backwards because we will be adding and removing channels
  343. for (int channelIndex = channelCount -1; channelIndex >= 0 ; --channelIndex)
  344. {
  345. AnimationChannel* channel = animation->getAnimationChannel(channelIndex);
  346. assert(channel);
  347. // get target node
  348. const Object* obj = _refTable.get(channel->getTargetId());
  349. if (obj && obj->getTypeId() == Object::NODE_ID)
  350. {
  351. const Node* node = static_cast<const Node*>(obj);
  352. if (node->isJoint() && channel->getTargetAttribute() == Transform::ANIMATE_SCALE_ROTATE_TRANSLATE)
  353. {
  354. decomposeTransformAnimationChannel(animation, channel);
  355. animation->remove(channel);
  356. SAFE_DELETE(channel);
  357. }
  358. }
  359. }
  360. }
  361. }
  362. void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const AnimationChannel* channel)
  363. {
  364. const std::vector<float>& keyTimes = channel->getKeyTimes();
  365. const std::vector<float>& keyValues = channel->getKeyValues();
  366. const size_t keyTimesSize = keyTimes.size();
  367. const size_t keyValuesSize = keyValues.size();
  368. std::vector<float> scaleKeyValues;
  369. std::vector<float> rotateKeyValues;
  370. std::vector<float> translateKeyValues;
  371. scaleKeyValues.reserve(keyTimesSize * 3);
  372. rotateKeyValues.reserve(keyTimesSize * 4);
  373. translateKeyValues.reserve(keyTimesSize * 3);
  374. for (size_t kv = 0; kv < keyValuesSize; kv += 10)
  375. {
  376. scaleKeyValues.push_back(keyValues[kv]);
  377. scaleKeyValues.push_back(keyValues[kv+1]);
  378. scaleKeyValues.push_back(keyValues[kv+2]);
  379. rotateKeyValues.push_back(keyValues[kv+3]);
  380. rotateKeyValues.push_back(keyValues[kv+4]);
  381. rotateKeyValues.push_back(keyValues[kv+5]);
  382. rotateKeyValues.push_back(keyValues[kv+6]);
  383. translateKeyValues.push_back(keyValues[kv+7]);
  384. translateKeyValues.push_back(keyValues[kv+8]);
  385. translateKeyValues.push_back(keyValues[kv+9]);
  386. }
  387. // replace transform animation channel with translate, rotate and scale animation channels
  388. // Don't add the scale channel if all the key values are close to 1.0
  389. size_t oneCount = (size_t)std::count_if(scaleKeyValues.begin(), scaleKeyValues.end(), isAlmostOne);
  390. if (scaleKeyValues.size() != oneCount)
  391. {
  392. AnimationChannel* scaleChannel = new AnimationChannel();
  393. scaleChannel->setTargetId(channel->getTargetId());
  394. scaleChannel->setKeyTimes(channel->getKeyTimes());
  395. scaleChannel->setTangentsIn(channel->getTangentsIn());
  396. scaleChannel->setTangentsOut(channel->getTangentsOut());
  397. scaleChannel->setInterpolations(channel->getInterpolationTypes());
  398. scaleChannel->setTargetAttribute(Transform::ANIMATE_SCALE);
  399. scaleChannel->setKeyValues(scaleKeyValues);
  400. scaleChannel->removeDuplicates();
  401. animation->add(scaleChannel);
  402. }
  403. AnimationChannel* rotateChannel = new AnimationChannel();
  404. rotateChannel->setTargetId(channel->getTargetId());
  405. rotateChannel->setKeyTimes(channel->getKeyTimes());
  406. rotateChannel->setTangentsIn(channel->getTangentsIn());
  407. rotateChannel->setTangentsOut(channel->getTangentsOut());
  408. rotateChannel->setInterpolations(channel->getInterpolationTypes());
  409. rotateChannel->setTargetAttribute(Transform::ANIMATE_ROTATE);
  410. rotateChannel->setKeyValues(rotateKeyValues);
  411. rotateChannel->removeDuplicates();
  412. animation->add(rotateChannel);
  413. AnimationChannel* translateChannel = new AnimationChannel();
  414. translateChannel->setTargetId(channel->getTargetId());
  415. translateChannel->setKeyTimes(channel->getKeyTimes());
  416. translateChannel->setTangentsIn(channel->getTangentsIn());
  417. translateChannel->setTangentsOut(channel->getTangentsOut());
  418. translateChannel->setInterpolations(channel->getInterpolationTypes());
  419. translateChannel->setTargetAttribute(Transform::ANIMATE_TRANSLATE);
  420. translateChannel->setKeyValues(translateKeyValues);
  421. translateChannel->removeDuplicates();
  422. animation->add(translateChannel);
  423. }
  424. void GPBFile::moveAnimationChannels(Node* node, Animation* dstAnimation)
  425. {
  426. // Loop through the animations and channels backwards because they will be removed when found.
  427. int animationCount = _animations.getAnimationCount();
  428. for (int i = animationCount - 1; i >= 0; --i)
  429. {
  430. Animation* animation = _animations.getAnimation(i);
  431. int channelCount = animation->getAnimationChannelCount();
  432. for (int j = channelCount - 1; j >= 0; --j)
  433. {
  434. AnimationChannel* channel = animation->getAnimationChannel(j);
  435. if (equals(channel->getTargetId(), node->getId()))
  436. {
  437. animation->remove(channel);
  438. dstAnimation->add(channel);
  439. }
  440. }
  441. if (animation->getAnimationChannelCount() == 0)
  442. {
  443. _animations.removeAnimation(i);
  444. }
  445. }
  446. for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
  447. {
  448. moveAnimationChannels(child, dstAnimation);
  449. }
  450. }
  451. bool isAlmostOne(float value)
  452. {
  453. return std::fabs(value - 1.0f) < EPSILON;
  454. }
  455. Node* getCommonNodeAncestor(const std::vector<Node*>& nodes)
  456. {
  457. if (nodes.empty())
  458. return NULL;
  459. if (nodes.size() == 1)
  460. return nodes.front();
  461. std::list<Node*> ancestors;
  462. size_t minAncestorCount = INT_MAX;
  463. for (std::vector<Node*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
  464. {
  465. Node* node = *it;
  466. getNodeAncestors(node, ancestors);
  467. ancestors.push_back(node);
  468. minAncestorCount = std::min(minAncestorCount, ancestors.size());
  469. }
  470. ancestors.resize(minAncestorCount);
  471. return ancestors.back();
  472. }
  473. void getNodeAncestors(Node* node, std::list<Node*>& ancestors)
  474. {
  475. ancestors.clear();
  476. Node* parent = node->getParent();
  477. while (parent != NULL)
  478. {
  479. ancestors.push_front(parent);
  480. parent = parent->getParent();
  481. }
  482. }
  483. }