AnimationExtractor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "AnimationExtractor.h"
  2. #include "../../common/Logger.h"
  3. void
  4. AnimationExtractor( const Ogre::SkeletonPtr& skeleton, const ModelInfo& info, Skeleton& skeleton_data )
  5. {
  6. if( info.animations.size() != info.animations_name.size() )
  7. {
  8. LOGGER->Log( "AnimationExtractor ERROR: number of animations dont match number of animation names.\n" );
  9. return;
  10. }
  11. float fps = 25.0f;
  12. for( size_t i = 0; i < info.animations.size(); ++i )
  13. {
  14. if( info.animations[ i ] == "" || info.animations_name[ i ] == "" )
  15. {
  16. continue;
  17. }
  18. File* file = new File( "./data/field/" + info.animations[ i ] );
  19. LOGGER->Log( "AnimationExtractor: " + Ogre::StringConverter::toString( i ) + " " + info.animations[ i ] + " as animation with name " + info.animations_name[ i ] + "\n" );
  20. int number_of_frames = file->GetU16LE( 0x2 );
  21. Ogre::Animation* anim = skeleton->createAnimation( info.animations_name[ i ], ( number_of_frames - 1 ) / fps );
  22. float time = 0;
  23. float tx, ty, tz;
  24. u32 raw_rx, raw_ry, raw_rz;
  25. float rx, ry, rz;
  26. Ogre::Bone* bone1;
  27. Ogre::Bone* bone2;
  28. Ogre::NodeAnimationTrack* track1;
  29. Ogre::NodeAnimationTrack* track2;
  30. Ogre::TransformKeyFrame* frame1;
  31. Ogre::TransformKeyFrame* frame2;
  32. Ogre::Quaternion rot;
  33. Ogre::Matrix3 mat;
  34. for ( int frame = 0; frame < number_of_frames; ++frame )
  35. {
  36. // this is just to orientate model to right direction
  37. if( frame == 0 )
  38. {
  39. bone1 = skeleton->getBone( 0 );
  40. track1 = anim->createNodeTrack( 0, bone1 );
  41. track1->removeAllKeyFrames();
  42. frame1 = track1->createNodeKeyFrame( time );
  43. mat.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian( Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) );
  44. rot.FromRotationMatrix( mat );
  45. frame1->setRotation( rot );
  46. bone2 = skeleton->getBone( 1 );
  47. track2 = anim->createNodeTrack( 1, bone2 );
  48. track2->removeAllKeyFrames();
  49. }
  50. else
  51. {
  52. bone1 = skeleton->getBone( 0 );
  53. track1 = anim->getNodeTrack( 0 );
  54. frame1 = track1->createNodeKeyFrame( time );
  55. mat.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian(Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) );
  56. rot.FromRotationMatrix( mat );
  57. frame1->setRotation( rot );
  58. bone2 = skeleton->getBone( 1 );
  59. track2 = anim->getNodeTrack( 1 );
  60. }
  61. frame2 = track2->createNodeKeyFrame( time );
  62. u32 high_angle_offset = file->GetU32LE( 0xc );
  63. u32 low_angle_offset = file->GetU32LE( 0x10 );
  64. for( int bone = 0; bone < skeleton_data.size(); ++bone )
  65. {
  66. tx = 0; ty = 0; tz = 0;
  67. rx = 0; ry = 0; rz = 0;
  68. raw_rx = 0; raw_ry = 0; raw_rz = 0;
  69. if( bone == 0 )
  70. {
  71. // create root translation
  72. u16 flags = file->GetU16LE( 0xa );
  73. if( flags & 1 )
  74. {
  75. tx = ( s16 )file->GetU16LE( 0x4 );
  76. }
  77. else
  78. {
  79. u16 offset = file->GetU16LE( 0x4 );
  80. tx = ( s16 )file->GetU16LE( offset + frame * 2 );
  81. }
  82. if( flags & 2 )
  83. {
  84. ty = ( s16 )file->GetU16LE( 0x6 );
  85. }
  86. else
  87. {
  88. u16 offset = file->GetU16LE( 0x6 );
  89. ty = ( s16 )file->GetU16LE( offset + frame * 2 );
  90. }
  91. if( flags & 4 )
  92. {
  93. tz = ( s16 )file->GetU16LE( 0x8 );
  94. }
  95. else
  96. {
  97. u16 offset = file->GetU16LE( 0x8 );
  98. tz = ( s16 )file->GetU16LE( offset + frame * 2 );
  99. }
  100. }
  101. u16 flags = file->GetU16LE( high_angle_offset + 0x6 );
  102. u16 data = file->GetU16LE( high_angle_offset + 0x0 );
  103. //LOGGER->Log( "AnimationExtractor: data_x = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  104. if( ( flags & 1 ) == 0 )
  105. {
  106. data = file->GetU8( data + frame );
  107. //LOGGER->Log( "AnimationExtractor: flagged data_x = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  108. }
  109. raw_rx = ( data & 0xff ) << 4;
  110. data = file->GetU16LE( high_angle_offset + 0x2 );
  111. //LOGGER->Log( "AnimationExtractor: data_y = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  112. if( ( flags & 2 ) == 0 )
  113. {
  114. data = file->GetU8( data + frame );
  115. //LOGGER->Log( "AnimationExtractor: flagged data_y = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  116. }
  117. raw_ry = ( data & 0xff ) << 4;
  118. data = file->GetU16LE( high_angle_offset + 0x4 );
  119. //LOGGER->Log( "AnimationExtractor: data_z = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  120. if( ( flags & 4 ) == 0 )
  121. {
  122. data = file->GetU8( data + frame );
  123. //LOGGER->Log( "AnimationExtractor: flagged data_z = 0x" + ToHexString( data, 4, '0' ) + ".\n" );
  124. }
  125. raw_rz = ( data & 0xff ) << 4;
  126. //LOGGER->Log( "AnimationExtractor: GET ROTATION frame = " + Ogre::StringConverter::toString( frame ) + ", bone = " + Ogre::StringConverter::toString( bone ) + ", flags = 0x" + ToHexString( flags, 4, '0' ) + ", high_rx = 0x" + ToHexString( raw_rx, 4, '0' ) + ", high_ry = 0x" + ToHexString( raw_ry, 4, '0' ) + ", high_rz = 0x" + ToHexString( raw_rz, 4, '0' ) + ".\n" );
  127. // if there is low range angles
  128. if( low_angle_offset != 0 )
  129. {
  130. flags = file->GetU16LE( low_angle_offset + 0x6 );
  131. u16 data = file->GetU16LE( low_angle_offset + 0x0 );
  132. if( ( flags & 1 ) == 0 )
  133. {
  134. data = file->GetU8( data + frame / 2 );
  135. if( frame & 1 )
  136. {
  137. data >>= 4;
  138. }
  139. }
  140. raw_rx |= data & 0xf;
  141. data = file->GetU16LE( low_angle_offset + 0x2 );
  142. if( ( flags & 2 ) == 0 )
  143. {
  144. data = file->GetU8( data + frame / 2 );
  145. if( frame & 1 )
  146. {
  147. data >>= 4;
  148. }
  149. }
  150. raw_ry |= data & 0xf;
  151. data = file->GetU16LE( low_angle_offset + 0x4 );
  152. if( ( flags & 4 ) == 0 )
  153. {
  154. data = file->GetU8( data + frame / 2 );
  155. if( frame & 1 )
  156. {
  157. data >>= 4;
  158. }
  159. }
  160. raw_rz |= data & 0xf;
  161. //LOGGER->Log( "AnimationExtractor: GET ROTATION frame = " + Ogre::StringConverter::toString( frame ) + ", bone = " + Ogre::StringConverter::toString( bone ) + ", low_flags = 0x" + ToHexString( flags, 4, '0' ) + ", total_rx = 0x" + ToHexString( raw_rx, 4, '0' ) + ", total_ry = 0x" + ToHexString( raw_ry, 4, '0' ) + ", total_rz = 0x" + ToHexString( raw_rz, 4, '0' ) + ".\n" );
  162. low_angle_offset += 8;
  163. }
  164. high_angle_offset += 8;
  165. rx = ( raw_rx / 4096.0f ) * 360.0f;
  166. ry = ( raw_ry / 4096.0f ) * 360.0f;
  167. rz = ( raw_rz / 4096.0f ) * 360.0f;
  168. // assign data to bone
  169. bone1 = skeleton->getBone( bone * 2 + 2 );
  170. bone2 = skeleton->getBone( bone * 2 + 3 );
  171. if( frame == 0 )
  172. {
  173. track1 = anim->createNodeTrack( bone * 2 + 2, bone1 );
  174. track1->removeAllKeyFrames();
  175. track2 = anim->createNodeTrack( bone * 2 + 3, bone2 );
  176. track2->removeAllKeyFrames();
  177. }
  178. else
  179. {
  180. track1 = anim->getNodeTrack( bone * 2 + 2 );
  181. track2 = anim->getNodeTrack( bone * 2 + 3 );
  182. }
  183. frame1 = track1->createNodeKeyFrame( time );
  184. frame2 = track2->createNodeKeyFrame( time );
  185. Ogre::Vector3 translate = Ogre::Vector3( tx, ty, tz + skeleton_data[ bone ].length ) / 512.0f;
  186. //LOGGER->Log( "AnimationExtractor: frame = " + Ogre::StringConverter::toString( frame ) + ", bone = " + Ogre::StringConverter::toString( bone ) + ", translation = " + Ogre::StringConverter::toString( translate ) + ".\n" );
  187. frame1->setTranslate( translate );
  188. //mat.FromEulerAnglesXYZ( Ogre::Radian( Ogre::Degree( rx ) ), Ogre::Radian( Ogre::Degree( ry ) ), Ogre::Radian( Ogre::Degree( rz ) ) );
  189. //mat.FromEulerAnglesXZY( Ogre::Radian( Ogre::Degree( rx ) ), Ogre::Radian( Ogre::Degree( rz ) ), Ogre::Radian( Ogre::Degree( ry ) ) );
  190. //mat.FromEulerAnglesYZX( Ogre::Radian( Ogre::Degree( ry ) ), Ogre::Radian( Ogre::Degree( rz ) ), Ogre::Radian( Ogre::Degree( rx ) ) );
  191. //mat.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( ry ) ), Ogre::Radian( Ogre::Degree( rx ) ), Ogre::Radian( Ogre::Degree( rz ) ) );
  192. mat.FromEulerAnglesZYX( Ogre::Radian( Ogre::Degree( rz ) ), Ogre::Radian( Ogre::Degree( ry ) ), Ogre::Radian( Ogre::Degree( rx ) ) );
  193. //mat.FromEulerAnglesZXY( Ogre::Radian( Ogre::Degree( rz ) ), Ogre::Radian( Ogre::Degree( rx ) ), Ogre::Radian( Ogre::Degree( ry ) ) );
  194. //LOGGER->Log( "AnimationExtractor: frame = " + Ogre::StringConverter::toString( frame ) + ", bone = " + Ogre::StringConverter::toString( bone ) + ", rotation = " + Ogre::StringConverter::toString( rx ) + " " + Ogre::StringConverter::toString( ry ) + " " + Ogre::StringConverter::toString( rz ) + ".\n" );
  195. rot.FromRotationMatrix( mat );
  196. frame2->setRotation( rot );
  197. }
  198. time += 1.0f / fps;
  199. }
  200. delete file;
  201. }
  202. }