MeshExtractor.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #include "MeshExtractor.h"
  2. #define POSITION_BINDING 0
  3. #define COLOUR_BINDING 1
  4. #define TEXTURE_BINDING 2
  5. #include "../../common/Logger.h"
  6. #include "../../common/OgreGenUtilites.h"
  7. void
  8. MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh )
  9. {
  10. File* file12 = new File( "./data/field/5/1b/1/12/1" );
  11. u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff;
  12. LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" );
  13. u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4;
  14. LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" );
  15. int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 );
  16. int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 );
  17. int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 );
  18. int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 );
  19. int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a );
  20. int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c );
  21. int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e );
  22. int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 );
  23. u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 );
  24. u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 );
  25. u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c );
  26. u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 );
  27. Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */);
  28. sub_mesh->setMaterialName( material_name );
  29. sub_mesh->useSharedVertices = false;
  30. sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  31. // Allocate and prepare vertex data
  32. sub_mesh->vertexData = new Ogre::VertexData();
  33. sub_mesh->vertexData->vertexStart = 0;
  34. sub_mesh->vertexData->vertexCount = static_cast< size_t >(
  35. number_of_monochrome_textured_quads * 6 +
  36. number_of_monochrome_textured_triangles * 3/* +
  37. number_of_shaded_textured_quads * 6 +
  38. number_of_shaded_textured_triangles * 3 +
  39. number_of_gradated_quads * 6 +
  40. number_of_gradated_triangles * 3 +
  41. number_of_monochrome_quads * 6 +
  42. number_of_monochrome_triangles * 3*/ );
  43. sub_mesh->indexData = new Ogre::IndexData();
  44. sub_mesh->indexData->indexStart = 0;
  45. sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
  46. sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
  47. Ogre::HardwareIndexBuffer::IT_16BIT,
  48. sub_mesh->indexData->indexCount,
  49. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  50. u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
  51. u32 cur_index = 0;
  52. Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
  53. Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
  54. // 1st buffer
  55. decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  56. Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  57. decl->getVertexSize( POSITION_BINDING ),
  58. sub_mesh->vertexData->vertexCount,
  59. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  60. bind->setBinding( POSITION_BINDING, vbuf0 );
  61. // 2nd buffer
  62. decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
  63. Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  64. decl->getVertexSize( COLOUR_BINDING ),
  65. sub_mesh->vertexData->vertexCount,
  66. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  67. // Set vertex buffer binding so buffer 1 is bound to our colour buffer
  68. bind->setBinding( COLOUR_BINDING, vbuf1 );
  69. // 3rd buffer
  70. decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
  71. Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  72. decl->getVertexSize( TEXTURE_BINDING ),
  73. sub_mesh->vertexData->vertexCount,
  74. Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
  75. bind->setBinding( TEXTURE_BINDING, vbuf2 );
  76. float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
  77. float* tPos = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
  78. Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
  79. std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount);
  80. Ogre::RGBA* colours = coloursVec.data();
  81. for( int i = 0; i < number_of_monochrome_textured_quads; ++i )
  82. {
  83. int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
  84. int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
  85. int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
  86. int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 );
  87. Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
  88. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
  89. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
  90. Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
  91. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
  92. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
  93. Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
  94. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
  95. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
  96. Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ),
  97. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ),
  98. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) );
  99. a /= 512;
  100. b /= 512;
  101. c /= 512;
  102. d /= 512;
  103. int image_id = file->GetU8( pointer_to_mesh_data + 0x13 );
  104. u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
  105. u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
  106. LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
  107. /*
  108. int clut_x = (clut & 0x003f) << 3;
  109. int clut_y = (clut & 0xffc0) >> 6;
  110. int bpp = (tpage >> 0x7) & 0x3;
  111. int vram_x = (tpage & 0xf) * 64;
  112. int vram_y = ((tpage & 0x10) >> 4) * 256;
  113. */
  114. TexForGen texture;
  115. texture.palette_x = 128/*clut_x*/;
  116. texture.palette_y = 224/*clut_y*/;
  117. if( image_id == 1 )
  118. {
  119. texture.texture_x = 768/*vram_x*/;
  120. }
  121. else
  122. {
  123. texture.texture_x = 832/*vram_x*/;
  124. }
  125. texture.texture_y = 256/*vram_y*/;
  126. texture.bpp = BPP_8/*bpp*/;
  127. AddTexture( texture, mesh_data, textures, LOGGER );
  128. Ogre::Vector2 at( 0, 0 );
  129. Ogre::Vector2 bt( 0, 0 );
  130. Ogre::Vector2 ct( 0, 0 );
  131. Ogre::Vector2 dt( 0, 0 );
  132. u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 );
  133. at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  134. at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  135. u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa );
  136. bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  137. bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  138. u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
  139. ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  140. ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  141. u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
  142. dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  143. dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  144. *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
  145. *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
  146. *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
  147. *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
  148. *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
  149. *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;
  150. *tPos++ = at.x; *tPos++ = at.y;
  151. *tPos++ = ct.x; *tPos++ = ct.y;
  152. *tPos++ = bt.x; *tPos++ = bt.y;
  153. *tPos++ = bt.x; *tPos++ = bt.y;
  154. *tPos++ = ct.x; *tPos++ = ct.y;
  155. *tPos++ = dt.x; *tPos++ = dt.y;
  156. Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f,
  157. file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f,
  158. file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f,
  159. 1.0f );
  160. rs->convertColourValue( colour, colours + cur_index + 0 );
  161. rs->convertColourValue( colour, colours + cur_index + 1 );
  162. rs->convertColourValue( colour, colours + cur_index + 2 );
  163. rs->convertColourValue( colour, colours + cur_index + 3 );
  164. rs->convertColourValue( colour, colours + cur_index + 4 );
  165. rs->convertColourValue( colour, colours + cur_index + 5 );
  166. idata[ cur_index + 0 ] = cur_index + 0;
  167. idata[ cur_index + 1 ] = cur_index + 1;
  168. idata[ cur_index + 2 ] = cur_index + 2;
  169. idata[ cur_index + 3 ] = cur_index + 3;
  170. idata[ cur_index + 4 ] = cur_index + 4;
  171. idata[ cur_index + 5 ] = cur_index + 5;
  172. Ogre::VertexBoneAssignment vba;
  173. vba.weight = 1.0f;
  174. vba.vertexIndex = cur_index + 0;
  175. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
  176. sub_mesh->addBoneAssignment( vba );
  177. vba.vertexIndex = cur_index + 1;
  178. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
  179. sub_mesh->addBoneAssignment( vba );
  180. vba.vertexIndex = cur_index + 2;
  181. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
  182. sub_mesh->addBoneAssignment( vba );
  183. vba.vertexIndex = cur_index + 3;
  184. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
  185. sub_mesh->addBoneAssignment( vba );
  186. vba.vertexIndex = cur_index + 4;
  187. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
  188. sub_mesh->addBoneAssignment( vba );
  189. vba.vertexIndex = cur_index + 5;
  190. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3;
  191. sub_mesh->addBoneAssignment( vba );
  192. cur_index += 6;
  193. pointer_to_mesh_data += 0x18;
  194. }
  195. for( int i = 0; i < number_of_monochrome_textured_triangles; ++i )
  196. {
  197. int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
  198. int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
  199. int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
  200. Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
  201. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
  202. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
  203. Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
  204. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
  205. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
  206. Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
  207. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
  208. ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
  209. a /= 512;
  210. b /= 512;
  211. c /= 512;
  212. int image_id = file->GetU8( pointer_to_mesh_data + 0x6 );
  213. u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
  214. u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
  215. LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
  216. /*
  217. int clut_x = (clut & 0x003f) << 3;
  218. int clut_y = (clut & 0xffc0) >> 6;
  219. int bpp = (tpage >> 0x7) & 0x3;
  220. int vram_x = (tpage & 0xf) * 64;
  221. int vram_y = ((tpage & 0x10) >> 4) * 256;
  222. */
  223. TexForGen texture;
  224. texture.palette_x = 128/*clut_x*/;
  225. texture.palette_y = 224/*clut_y*/;
  226. if( image_id == 1 )
  227. {
  228. texture.texture_x = 768/*vram_x*/;
  229. }
  230. else
  231. {
  232. texture.texture_x = 832/*vram_x*/;
  233. }
  234. texture.texture_y = 256/*vram_y*/;
  235. texture.bpp = BPP_8/*bpp*/;
  236. AddTexture( texture, mesh_data, textures, LOGGER );
  237. Ogre::Vector2 at( 0, 0 );
  238. Ogre::Vector2 bt( 0, 0 );
  239. Ogre::Vector2 ct( 0, 0 );
  240. u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
  241. at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  242. at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  243. u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
  244. bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  245. bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  246. u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 );
  247. ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
  248. ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;
  249. *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
  250. *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
  251. *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
  252. *tPos++ = at.x; *tPos++ = at.y;
  253. *tPos++ = ct.x; *tPos++ = ct.y;
  254. *tPos++ = bt.x; *tPos++ = bt.y;
  255. Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f,
  256. file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f,
  257. file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f,
  258. 1.0f );
  259. rs->convertColourValue( colour, colours + cur_index + 0 );
  260. rs->convertColourValue( colour, colours + cur_index + 1 );
  261. rs->convertColourValue( colour, colours + cur_index + 2 );
  262. idata[ cur_index + 0 ] = cur_index + 0;
  263. idata[ cur_index + 1 ] = cur_index + 1;
  264. idata[ cur_index + 2 ] = cur_index + 2;
  265. Ogre::VertexBoneAssignment vba;
  266. vba.weight = 1.0f;
  267. vba.vertexIndex = cur_index + 0;
  268. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
  269. sub_mesh->addBoneAssignment( vba );
  270. vba.vertexIndex = cur_index + 1;
  271. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
  272. sub_mesh->addBoneAssignment( vba );
  273. vba.vertexIndex = cur_index + 2;
  274. vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
  275. sub_mesh->addBoneAssignment( vba );
  276. cur_index += 3;
  277. pointer_to_mesh_data += 0x14;
  278. }
  279. vbuf0->unlock();
  280. vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true );
  281. vbuf2->unlock();
  282. sub_mesh->indexData->indexBuffer->unlock();
  283. // Optimize index data
  284. sub_mesh->indexData->optimiseVertexCacheTriList();
  285. delete file12;
  286. }