| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #include "AnimationExtractor.h"
- #include "../../common/Logger.h"
- float
- ReadBitStream(File* file, const int offset, int &readed_bits, const int bit_to_read, const int real_size)
- {
- int ret = 0;
- for (int i = 0; i < bit_to_read; ++i)
- {
- ret <<= 1;
- // read new bit
- int byte = file->GetU8(offset + (readed_bits / 8));
- //LOGGER->Log(LOGGER_INFO, "ReadBitStream data = %02x readed_bits = %02x", byte, readed_bits);
- if ((byte >> (7 - (readed_bits & 7))) & 1)
- {
- ret |= 1;
- }
- readed_bits += 1;
- }
- // force the sign bit to extend across the 32-bit boundary.
- ret <<= (0x20 - bit_to_read);
- ret >>= (0x20 - bit_to_read);
- // extend compressed value
- ret <<= (real_size - bit_to_read);
- return (float)ret;
- }
- float
- ReadDynamicFrameOffsetBits(File* file, const int offset, int &readed_bits)
- {
- int readed_bytes = readed_bits / 8;
- int bit_in_byte = readed_bits & 7;
- int data = (file->GetU8(offset + readed_bytes + 0) << 8) | file->GetU8(offset + readed_bytes + 1);
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits data = %04x (bit_in_byte %02x)", data, bit_in_byte);
- if ((data & (1 << (15 - bit_in_byte))) != 0)
- {
- // 16 bit value
- data <<= 8;
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
- data |= file->GetU8(offset + readed_bytes + 2);
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
- data <<= (bit_in_byte + 9);
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
- data >>= 0x10;
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 16bit = %04x", data);
- readed_bits += 17;
- }
- else
- {
- // 7 bit value
- data <<= (bit_in_byte + 0x11);
- data >>= 0x19;
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits 7bit = %d", data);
- readed_bits += 8;
- }
- //LOGGER->Log(LOGGER_INFO, "ReadDynamicFrameOffsetBits = %d", data);
- return (float)data;
- }
- float
- ReadEncryptedRotationBits(File* file, const int offset, int &readed_bits, const int compression)
- {
- int ret = 0;
- int control_bit = ReadBitStream(file, offset, readed_bits, 1, 1);
- //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits control_bit = %x", control_bit);
- if (control_bit != 0)
- {
- control_bit = ReadBitStream(file, offset, readed_bits, 3, 3);
- control_bit &= 7;
- //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits control_bit = %x", control_bit);
- if (control_bit == 0)
- {
- ret = -1.0f;
- }
- else if (control_bit == 7)
- {
- ret = ReadBitStream(file, offset, readed_bits, 12 - compression, 12);
- }
- else
- {
- int data = ReadBitStream(file, offset, readed_bits, control_bit, control_bit);
- //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits data = %x", data);
- if (data >= 0)
- {
- data += (1 << (control_bit - 1));
- }
- else
- {
- data -= (1 << (control_bit - 1));
- }
- ret = data << (compression + 16);
- ret >>= 16;
- }
- }
- //LOGGER->Log(LOGGER_INFO, "ReadEncryptedRotationBits = %x", ret);
- return (float)ret;
- }
- void
- AnimationExtractor(File* file, const Ogre::SkeletonPtr& skeleton, const EnemyInfo& info, Skeleton& skeleton_data, bool with_weapon)
- {
- float weapon_tx, weapon_ty, weapon_tz, weapon_rx, weapon_ry, weapon_rz = 0;
- for (int i = 0; i < info.animations.size(); ++i)
- {
- if (info.animations[i] == "")
- {
- continue;
- }
- LOGGER->Log("AnimationExtractor:" + Ogre::StringConverter::toString(i) + " " + info.animations[i] + "\n");
- int offset_to_animation = file->GetU32LE(0x0c + i * 0x04);
- int offset_to_animation_weapon = 0;
- if (with_weapon)
- {
- offset_to_animation_weapon = file->GetU32LE(0x4c + i * 0x04);
- }
- int number_of_frames = file->GetU16LE(offset_to_animation + 0x0);
- int compression = file->GetU8(offset_to_animation + 0x4);
- int compression_weapon = 0;
- if (with_weapon)
- {
- compression_weapon = file->GetU8(offset_to_animation_weapon + 0x4);
- }
- Ogre::Animation* anim = skeleton->createAnimation(info.animations[i], (number_of_frames - 1) / 10.0f);
- float time = 0;
- int readed_bits = 0;
- int readed_bits_weapon = 0;
- float tx, ty, tz;
- Ogre::Bone* bone1;
- Ogre::Bone* bone2;
- Ogre::NodeAnimationTrack* track1;
- Ogre::NodeAnimationTrack* track2;
- Ogre::TransformKeyFrame* frame1;
- Ogre::TransformKeyFrame* frame2;
- Ogre::Quaternion rot;
- Ogre::Matrix3 mat;
- for (int frame = 0; frame < number_of_frames; ++frame)
- {
- if (readed_bits == 0)
- {
- tx = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
- ty = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
- tz = ReadBitStream(file, offset_to_animation + 5, readed_bits, 16, 16);
- // skip first rotation
- ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
- ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
- ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12);
- bone1 = skeleton->getBone(0);
- track1 = anim->createNodeTrack(0, bone1);
- track1->removeAllKeyFrames();
- frame1 = track1->createNodeKeyFrame(time);
- mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(-90)), Ogre::Radian(Ogre::Degree(0)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- bone2 = skeleton->getBone(1);
- track2 = anim->createNodeTrack(1, bone2);
- track2->removeAllKeyFrames();
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(tx, ty, tz) / 512);
- for (int bone = 0; bone < skeleton_data.size(); ++bone)
- {
- skeleton_data[bone].rx = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
- skeleton_data[bone].ry = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
- skeleton_data[bone].rz = (ReadBitStream(file, offset_to_animation + 5, readed_bits, 12 - compression, 12) / 4096.0f) * 360;
- bone1 = skeleton->getBone(bone * 2 + 2);
- bone2 = skeleton->getBone(bone * 2 + 3);
- track1 = anim->createNodeTrack(bone * 2 + 2, bone1);
- track1->removeAllKeyFrames();
- track2 = anim->createNodeTrack(bone * 2 + 3, bone2);
- track2->removeAllKeyFrames();
- frame1 = track1->createNodeKeyFrame(time);
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(0, 0, skeleton_data[bone].length) / 512);
- 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)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- }
- if (with_weapon)
- {
- weapon_tx = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
- weapon_ty = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
- weapon_tz = ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 16, 16);
- weapon_rx = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
- weapon_ry = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
- weapon_rz = (ReadBitStream(file, offset_to_animation_weapon + 5, readed_bits_weapon, 12 - compression_weapon, 12) / 4096.0f) * 360;
- bone1 = skeleton->getBone(skeleton_data.size() * 2 + 3);
- track1 = anim->createNodeTrack(skeleton_data.size() * 2 + 3, bone1);
- track1->removeAllKeyFrames();
- frame1 = track1->createNodeKeyFrame(time);
- mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(weapon_ry)), Ogre::Radian(Ogre::Degree(weapon_rx)), Ogre::Radian(Ogre::Degree(weapon_rz)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- bone2 = skeleton->getBone(skeleton_data.size() * 2 + 2);
- track2 = anim->createNodeTrack(skeleton_data.size() * 2 + 2, bone2);
- track2->removeAllKeyFrames();
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(weapon_tx, weapon_ty, weapon_tz) / 512);
- }
- }
- else
- {
- tx += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
- ty += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
- tz += ReadDynamicFrameOffsetBits(file, offset_to_animation + 5, readed_bits);
- // skip first rotation
- ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
- ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
- ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression);
- bone1 = skeleton->getBone(0);
- track1 = anim->getNodeTrack(0);
- frame1 = track1->createNodeKeyFrame(time);
- mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(-90)), Ogre::Radian(Ogre::Degree(0)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- bone2 = skeleton->getBone(1);
- track2 = anim->getNodeTrack(1);
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(tx, ty, tz) / 512);
- for (int bone = 0; bone < skeleton_data.size(); ++bone)
- {
- skeleton_data[bone].rx += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
- skeleton_data[bone].ry += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
- skeleton_data[bone].rz += (ReadEncryptedRotationBits(file, offset_to_animation + 5, readed_bits, compression) / 4096.0f) * 360;
- bone1 = skeleton->getBone(bone * 2 + 2);
- bone2 = skeleton->getBone(bone * 2 + 3);
- track1 = anim->getNodeTrack(bone * 2 + 2);
- track2 = anim->getNodeTrack(bone * 2 + 3);
- frame1 = track1->createNodeKeyFrame(time);
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(0, 0, skeleton_data[bone].length) / 512);
- 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)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- }
- if (with_weapon)
- {
- weapon_tx += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
- weapon_ty += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
- weapon_tz += ReadDynamicFrameOffsetBits(file, offset_to_animation_weapon + 5, readed_bits_weapon);
- weapon_rx += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
- weapon_ry += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
- weapon_rz += (ReadEncryptedRotationBits(file, offset_to_animation_weapon + 5, readed_bits_weapon, compression_weapon) / 4096.0f) * 360;
- bone1 = skeleton->getBone(skeleton_data.size() * 2 + 3);
- track1 = anim->getNodeTrack(skeleton_data.size() * 2 + 3);
- frame1 = track1->createNodeKeyFrame(time);
- mat.FromEulerAnglesYXZ(Ogre::Radian(Ogre::Degree(weapon_ry)), Ogre::Radian(Ogre::Degree(weapon_rx)), Ogre::Radian(Ogre::Degree(weapon_rz)));
- rot.FromRotationMatrix(mat);
- frame1->setRotation(rot);
- bone2 = skeleton->getBone(skeleton_data.size() * 2 + 2);
- track2 = anim->getNodeTrack(skeleton_data.size() * 2 + 2);
- frame2 = track2->createNodeKeyFrame(time);
- frame2->setTranslate(Ogre::Vector3(weapon_tx, weapon_ty, weapon_tz) / 512);
- }
- }
- time += 1.0f / 10.0f;
- }
- }
- }
|