FieldModel.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "FieldModel.h"
  2. #include "FieldFile.h"
  3. #include "ModelFile.h"
  4. #include "common/File.h"
  5. #include "common/Logger.h"
  6. #include "../../common/OgreGenUtilites.h"
  7. FieldModel::FieldModel()
  8. {
  9. }
  10. FieldModel::~FieldModel()
  11. {
  12. }
  13. void
  14. FieldModel::Export( const Ogre::String& model_file, const Ogre::String& texture_file )
  15. {
  16. MeshData data;
  17. data.name = "lahan";
  18. data.tex_width = 4096;
  19. data.tex_height = 512;
  20. VectorTexForGen textures;
  21. FieldFile* field_file = new FieldFile( model_file );
  22. File* export_file = field_file->Extract( 2 );
  23. delete field_file;
  24. int number_of_models = export_file->GetU32LE( 0x00 );
  25. for( int i = 0; i < number_of_models; ++i )
  26. {
  27. Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create( data.name + Ogre::StringConverter::toString( i ) + "export", "General" );
  28. Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create( data.name + Ogre::StringConverter::toString( i ) + "export", "General" );
  29. Ogre::Bone* root1 = skeleton->createBone( "0", 0 );
  30. Ogre::Bone* root2 = skeleton->createBone( "1", 1 );
  31. root1->addChild( root2 );
  32. Ogre::Animation* anim = skeleton->createAnimation( "Idle", 1 );
  33. Ogre::NodeAnimationTrack* track1 = anim->createNodeTrack( 0, root1 );
  34. track1->removeAllKeyFrames();
  35. Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame( 0 );
  36. Ogre::Matrix3 matrix;
  37. matrix.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian( Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) );
  38. Ogre::Quaternion rot;
  39. rot.FromRotationMatrix( matrix );
  40. frame1->setRotation( rot );
  41. Logger* export_text = new Logger( "exported/" + data.name + Ogre::StringConverter::toString( i ) + ".txt" );
  42. int mesh_offset = export_file->GetU32LE( 0x4 + i * 0x04 );
  43. int mesh_next_offset = ( i + 1 == number_of_models ) ? export_file->GetFileSize() : export_file->GetU32LE( 0x8 + i * 0x04 );
  44. int mesh_size = mesh_next_offset - mesh_offset;
  45. ModelFile* mesh_file = new ModelFile( export_file, mesh_offset, mesh_size );
  46. mesh_file->GetModel( mesh, data, textures, export_text );
  47. delete mesh_file;
  48. skeleton->optimiseAllAnimations();
  49. Ogre::SkeletonSerializer skeleton_serializer;
  50. skeleton_serializer.exportSkeleton( skeleton.getPointer(), "exported/models/field/maps/" + data.name + "/" + data.name + Ogre::StringConverter::toString( i ) + ".skeleton" );
  51. // Update bounds
  52. Ogre::AxisAlignedBox aabb( -999, -999, -999, 999, 999, 999 );
  53. mesh->_setBounds( aabb, false );
  54. mesh->_setBoundingSphereRadius( 999 );
  55. mesh->setSkeletonName( "models/field/maps/" + data.name + "/" + data.name + Ogre::StringConverter::toString( i ) + ".skeleton" );
  56. Ogre::MeshSerializer ser;
  57. ser.exportMesh( mesh.getPointer(), "exported/models/field/maps/" + data.name + "/" + data.name + Ogre::StringConverter::toString( i ) + ".mesh" );
  58. }
  59. // create and export textures for model
  60. if( textures.size() > 0 )
  61. {
  62. File* texture = new File( texture_file );
  63. Vram* vram = Vram::MakeInstance().release();
  64. for( u32 i = 0; i < texture->GetFileSize(); )
  65. {
  66. u32 texture_header_id = texture->GetU32LE( i + 0x00 );
  67. u16 texture_header_vram_x = texture->GetU16LE( i + 0x04 );
  68. u16 texture_header_vram_y = texture->GetU16LE( i + 0x06 );
  69. u16 texture_header_move_x = texture->GetU16LE( i + 0x08 );
  70. u16 texture_header_move_y = texture->GetU16LE( i + 0x0a );
  71. u16 texture_header_width = texture->GetU16LE( i + 0x0c );
  72. u16 texture_header_height = texture->GetU16LE( i + 0x0e );
  73. u32 number_of_chunk = texture->GetU32LE( i + 0x18 );
  74. u16 vram_x = ( texture_header_vram_x + texture_header_move_x ) * 2;
  75. u16 vram_y = texture_header_vram_y + texture_header_move_y;
  76. // move to data (header always in separate sector)
  77. u32 temp_i = i;
  78. i += 0x0800;
  79. for( u32 j = 0; j < number_of_chunk; ++j )
  80. {
  81. // get height of current chunk
  82. u16 height = texture->GetU16LE( temp_i + 0x1C + j * 0x02 );
  83. //LOGGER->Log("texture_header_width = " + ToHexString(texture_header_width, 8, '0') + "\n");
  84. //LOGGER->Log("height = " + ToHexString(height, 8, '0') + "\n");
  85. //LOGGER->Log("vram_x = " + ToHexString(vram_x, 8, '0') + "\n");
  86. //LOGGER->Log("vram_y = " + ToHexString(vram_y, 8, '0') + "\n");
  87. // palette
  88. if( texture_header_id == 0x00001201 )
  89. {
  90. for( int y = 0; y < height; ++y )
  91. {
  92. for( int x = 0; x < texture_header_width; ++x )
  93. {
  94. u16 color = texture->GetU16LE( i + x * 0x02 + y * texture_header_width * 0x02 );
  95. vram->PutU16( x * 2 + vram_x, y + vram_y, color );
  96. //LOGGER->Log("put color (" + ToHexString(color, 8, '0') + ") to x (" + ToHexString(x * 2 + vram_x, 8, '0') + ") y (" + ToHexString(y + vram_y, 8, '0') + ")\n");
  97. }
  98. }
  99. }
  100. // textures
  101. else if( texture_header_id == 0x00001200 )
  102. {
  103. for( int y = 0; y < height; ++y )
  104. {
  105. for( int x = 0; x < texture_header_width * 2; ++x )
  106. {
  107. u8 data = texture->GetU8( i + x + y * texture_header_width * 2 );
  108. vram->PutU8( x + vram_x, y + vram_y, data );
  109. }
  110. }
  111. }
  112. // move pointer to start of next texture
  113. i += ceil( ( float )( texture_header_width * 2 * height) / 0x0800 ) * 0x0800;
  114. // update height
  115. texture_header_height += height;
  116. vram_y += height;
  117. }
  118. }
  119. //vram->Save( "1.png" );
  120. CreateTexture( vram, data, "exported/models/field/maps/" + data.name + "/" + data.name + ".png", textures );
  121. delete vram;
  122. delete texture;
  123. }
  124. CreateMaterial( "xeno/field/" + data.name, "exported/models/field/maps/" + data.name + "/" + data.name + ".material", (textures.size() > 0) ? "models/field/maps/" + data.name + "/" + data.name + ".png" : "", "", "" );
  125. for( int i = 0; i < number_of_models; ++i )
  126. {
  127. Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" );
  128. Ogre::Entity* thisEntity = scene_manager->createEntity( data.name + Ogre::StringConverter::toString( i ), "models/field/maps/" + data.name + "/" + data.name + Ogre::StringConverter::toString( i ) + ".mesh" );
  129. thisEntity->setVisible( true );
  130. thisEntity->getAnimationState( "Idle" )->setEnabled( true );
  131. thisEntity->getAnimationState( "Idle" )->setLoop( true );
  132. Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode();
  133. thisSceneNode->setPosition( 0, 0, 0 );
  134. thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) );
  135. thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) );
  136. thisSceneNode->pitch( Ogre::Radian( Ogre::Degree( 90.0f ) ) );
  137. thisSceneNode->attachObject( thisEntity );
  138. }
  139. delete export_file;
  140. }