AnimationExtractor.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #include "AnimationExtractor.h"
  2. #include "../../common/Logger.h"
  3. float
  4. ReadBitStream(File* file, const int offset, int &readed_bits, const int bit_to_read, const int real_size)
  5. {
  6. int ret = 0;
  7. for (int i = 0; i < bit_to_read; ++i)
  8. {
  9. ret <<= 1;
  10. // read new bit
  11. int byte = file->GetU8(offset + (readed_bits / 8));
  12. //LOGGER->Log(LOGGER_INFO, "ReadBitStream data = %02x readed_bits = %02x", byte, readed_bits);
  13. if ((byte >> (7 - (readed_bits & 7))) & 1)
  14. {
  15. ret |= 1;
  16. }
  17. readed_bits += 1;
  18. }
  19. // force the sign bit to extend across the 32-bit boundary.
  20. ret <<= (0x20 - bit_to_read);
  21. ret >>= (0x20 - bit_to_read);
  22. // extend compressed value
  23. ret <<= (real_size - bit_to_read);
  24. return (float)ret;
  25. }
  26. float
  27. ReadDynamicFrameOffsetBits(File* file, const int offset, int &readed_bits)
  28. {
  29. int readed_bytes = readed_bits / 8;
  30. int bit_in_byte = readed_bits & 7;
  31. int data = (file->GetU8(offset + readed_bytes + 0) << 8) | file->GetU8(offset + readed_bytes + 1);
  32. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits data = %04x (bit_in_byte %02x)", data, bit_in_byte);
  33. if ((data & (1 << (15 - bit_in_byte))) != 0)
  34. {
  35. // 16 bit value
  36. data <<= 8;
  37. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
  38. data |= file->GetU8(offset + readed_bytes + 2);
  39. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
  40. data <<= (bit_in_byte + 9);
  41. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
  42. data >>= 0x10;
  43. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
  44. readed_bits += 17;
  45. }
  46. else
  47. {
  48. // 7 bit value
  49. data <<= (bit_in_byte + 0x11);
  50. data >>= 0x19;
  51. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 7bit = %d", data);
  52. readed_bits += 8;
  53. }
  54. //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits = %d", data);
  55. return (float)data;
  56. }
  57. float
  58. ReadEncryptedRotationBits(File* file, const int offset, int &readed_bits, const int compression)
  59. {
  60. int ret = 0;
  61. int control_bit = ReadBitStream(file, offset, readed_bits, 1, 1);
  62. //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits control_bit = %x", control_bit);
  63. if (control_bit != 0)
  64. {
  65. control_bit = ReadBitStream(file, offset, readed_bits, 3, 3);
  66. control_bit &= 7;
  67. //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits control_bit = %x", control_bit);
  68. if (control_bit == 0)
  69. {
  70. ret = -1.0f;
  71. }
  72. else if (control_bit == 7)
  73. {
  74. ret = ReadBitStream(file, offset, readed_bits, 12 - compression, 12);
  75. }
  76. else
  77. {
  78. int data = ReadBitStream(file, offset, readed_bits, control_bit, control_bit);
  79. //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits data = %x", data);
  80. if (data >= 0)
  81. {
  82. data += (1 << (control_bit - 1));
  83. }
  84. else
  85. {
  86. data -= (1 << (control_bit - 1));
  87. }
  88. ret = data << (compression + 16);
  89. ret >>= 16;
  90. }
  91. }
  92. //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits = %x", ret);
  93. return (float)ret;
  94. }
  95. void
  96. AnimationExtractor(File* file, const Ogre::SkeletonPtr& skeleton, const EnemyInfo& info, Skeleton& skeleton_data, bool with_weapon)
  97. {
  98. float weapon_tx, weapon_ty, weapon_tz, weapon_rx, weapon_ry, weapon_rz = 0;
  99. for (int i = 0; i < info.animations.size(); ++i)
  100. {
  101. if (info.animations[i] == "")
  102. {
  103. continue;
  104. }
  105. LOGGER->Log("AnimationExtractor:" + Ogre::StringConverter::toString(i) + " " + info.animations[i] + "\n");
  106. int offset_to_animation = file->GetU32LE(0x0c + i * 0x04);
  107. int offset_to_animation_weapon = 0;
  108. if (with_weapon)
  109. {
  110. offset_to_animation_weapon = file->GetU32LE(0x4c + i * 0x04);
  111. }
  112. int number_of_frames = file->GetU16LE(offset_to_animation + 0x0);
  113. int compression = file->GetU8(offset_to_animation + 0x4);
  114. int compression_weapon = 0;
  115. if (with_weapon)
  116. {
  117. compression_weapon = file->GetU8(offset_to_animation_weapon + 0x4);
  118. }
  119. Ogre::Animation* anim = skeleton->createAnimation(info.animations[i], (number_of_frames - 1) / 10.0f);
  120. float time = 0;
  121. int readed_bits = 0;
  122. int readed_bits_weapon = 0;
  123. float tx, ty, tz;
  124. Ogre::Bone* bone1;
  125. Ogre::Bone* bone2;
  126. Ogre::NodeAnimationTrack* track1;
  127. Ogre::NodeAnimationTrack* track2;
  128. Ogre::TransformKeyFrame* frame1;
  129. Ogre::TransformKeyFrame* frame2;
  130. Ogre::Quaternion rot;
  131. Ogre::Matrix3 mat;
  132. for (int frame = 0; frame < number_of_frames; ++frame)
  133. {
  134. if (readed_bits == 0)
  135. {
  136. tx = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
  137. ty = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
  138. tz = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
  139. // skip first rotation
  140. ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
  141. ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
  142. ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
  143. bone1 = skeleton->getBone(0);
  144. track1 = anim->createNodeTrack(0, bone1);
  145. track1->removeAllKeyFrames();
  146. frame1 = track1->createNodeKeyFrame(time);
  147. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(-90)), Ogre::Radian(Ogre::Degree(0)));
  148. rot.FromRotationMatrix(mat);
  149. frame1->setRotation(rot);
  150. bone2 = skeleton->getBone(1);
  151. track2 = anim->createNodeTrack(1, bone2);
  152. track2->removeAllKeyFrames();
  153. frame2 = track2->createNodeKeyFrame(time);
  154. frame2->setTranslate(Ogre::Vector3(tx, ty, tz) / 512);
  155. for (int bone = 0; bone < skeleton_data.size(); ++bone)
  156. {
  157. skeleton_data[bone].rx = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
  158. skeleton_data[bone].ry = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
  159. skeleton_data[bone].rz = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
  160. bone1 = skeleton->getBone(bone * 2 + 2);
  161. bone2 = skeleton->getBone(bone * 2 + 3);
  162. track1 = anim->createNodeTrack(bone * 2 + 2, bone1);
  163. track1->removeAllKeyFrames();
  164. track2 = anim->createNodeTrack(bone * 2 + 3, bone2);
  165. track2->removeAllKeyFrames();
  166. frame1 = track1->createNodeKeyFrame(time);
  167. frame2 = track2->createNodeKeyFrame(time);
  168. frame2->setTranslate(Ogre::Vector3(0, 0, skeleton_data[bone].length) / 512);
  169. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(skeleton_data[bone].ry)), Ogre::Radian(Ogre::Degree(skeleton_data[bone].rx)), Ogre::Radian(Ogre::Degree(skeleton_data[bone].rz)));
  170. rot.FromRotationMatrix(mat);
  171. frame1->setRotation(rot);
  172. }
  173. if (with_weapon)
  174. {
  175. weapon_tx = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
  176. weapon_ty = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
  177. weapon_tz = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
  178. weapon_rx = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
  179. weapon_ry = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
  180. weapon_rz = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
  181. bone1 = skeleton->getBone(skeleton_data.size() * 2 + 3);
  182. track1 = anim->createNodeTrack(skeleton_data.size() * 2 + 3, bone1);
  183. track1->removeAllKeyFrames();
  184. frame1 = track1->createNodeKeyFrame(time);
  185. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(weapon_ry)), Ogre::Radian(Ogre::Degree(weapon_rx)), Ogre::Radian(Ogre::Degree(weapon_rz)));
  186. rot.FromRotationMatrix(mat);
  187. frame1->setRotation(rot);
  188. bone2 = skeleton->getBone(skeleton_data.size() * 2 + 2);
  189. track2 = anim->createNodeTrack(skeleton_data.size() * 2 + 2, bone2);
  190. track2->removeAllKeyFrames();
  191. frame2 = track2->createNodeKeyFrame(time);
  192. frame2->setTranslate(Ogre::Vector3(weapon_tx, weapon_ty, weapon_tz) / 512);
  193. }
  194. }
  195. else
  196. {
  197. tx += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
  198. ty += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
  199. tz += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
  200. // skip first rotation
  201. ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
  202. ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
  203. ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
  204. bone1 = skeleton->getBone(0);
  205. track1 = anim->getNodeTrack(0);
  206. frame1 = track1->createNodeKeyFrame(time);
  207. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(-90)), Ogre::Radian(Ogre::Degree(0)));
  208. rot.FromRotationMatrix(mat);
  209. frame1->setRotation(rot);
  210. bone2 = skeleton->getBone(1);
  211. track2 = anim->getNodeTrack(1);
  212. frame2 = track2->createNodeKeyFrame(time);
  213. frame2->setTranslate(Ogre::Vector3(tx, ty, tz) / 512);
  214. for (int bone = 0; bone < skeleton_data.size(); ++bone)
  215. {
  216. skeleton_data[bone].rx += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
  217. skeleton_data[bone].ry += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
  218. skeleton_data[bone].rz += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
  219. bone1 = skeleton->getBone(bone * 2 + 2);
  220. bone2 = skeleton->getBone(bone * 2 + 3);
  221. track1 = anim->getNodeTrack(bone * 2 + 2);
  222. track2 = anim->getNodeTrack(bone * 2 + 3);
  223. frame1 = track1->createNodeKeyFrame(time);
  224. frame2 = track2->createNodeKeyFrame(time);
  225. frame2->setTranslate(Ogre::Vector3(0, 0, skeleton_data[bone].length) / 512);
  226. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(skeleton_data[bone].ry)), Ogre::Radian(Ogre::Degree(skeleton_data[bone].rx)), Ogre::Radian(Ogre::Degree(skeleton_data[bone].rz)));
  227. rot.FromRotationMatrix(mat);
  228. frame1->setRotation(rot);
  229. }
  230. if (with_weapon)
  231. {
  232. weapon_tx += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
  233. weapon_ty += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
  234. weapon_tz += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
  235. weapon_rx += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
  236. weapon_ry += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
  237. weapon_rz += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
  238. bone1 = skeleton->getBone(skeleton_data.size() * 2 + 3);
  239. track1 = anim->getNodeTrack(skeleton_data.size() * 2 + 3);
  240. frame1 = track1->createNodeKeyFrame(time);
  241. mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(weapon_ry)), Ogre::Radian(Ogre::Degree(weapon_rx)), Ogre::Radian(Ogre::Degree(weapon_rz)));
  242. rot.FromRotationMatrix(mat);
  243. frame1->setRotation(rot);
  244. bone2 = skeleton->getBone(skeleton_data.size() * 2 + 2);
  245. track2 = anim->getNodeTrack(skeleton_data.size() * 2 + 2);
  246. frame2 = track2->createNodeKeyFrame(time);
  247. frame2->setTranslate(Ogre::Vector3(weapon_tx, weapon_ty, weapon_tz) / 512);
  248. }
  249. }
  250. time += 1.0f / 10.0f;
  251. }
  252. }
  253. }