From c7a864335f31d14f81e2e0c7b5e3743cbed1ff6f Mon Sep 17 00:00:00 2001 From: Mordred Date: Mon, 16 Oct 2017 23:54:27 +0200 Subject: [PATCH] hopefully fixed issues with pcb --- CMakeLists.txt | 1 + src/tools/pcb_reader/CMakeLists.txt | 15 +- src/tools/pcb_reader/main.cpp | 209 ++++++++++++++++++++++++++-- src/tools/pcb_reader/pcb.h | 1 + 4 files changed, 203 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e9a4b09..c153a1ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,3 +59,4 @@ add_subdirectory("src/servers") add_subdirectory("src/libraries/sapphire/datReader") add_subdirectory("src/tools/exd_common_gen") add_subdirectory("src/tools/quest_parser") +add_subdirectory("src/tools/pcb_reader") diff --git a/src/tools/pcb_reader/CMakeLists.txt b/src/tools/pcb_reader/CMakeLists.txt index 9bd07e39..6a314a46 100644 --- a/src/tools/pcb_reader/CMakeLists.txt +++ b/src/tools/pcb_reader/CMakeLists.txt @@ -6,18 +6,13 @@ include_directories("../") file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*") file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.cpp") -SET(Boost_USE_STATIC_LIBS ON) -set(Boost_INCLUDE_DIR /opt/build_libs/boost_1_60_0) -set(Boost_LIBRARY_DIR /opt/build_libs/boost_1_60_0/stage/lib) -set(SERVER_COMMON_DIR ../../servers/Server_Common) -find_package(Boost COMPONENTS log log_setup thread date_time filesystem system REQUIRED) -include_directories(${Boost_INCLUDE_DIR}) - -link_directories(${Boost_LIBRARY_DIR}) -link_directories(${SERVER_COMMON_DIR}) #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") add_executable(pcb_parser2 ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) -target_link_libraries (pcb_parser2 server_common.a pthread mysqlclient dl z) +if (UNIX) + target_link_libraries (pcb_parser2 Common xivdat pthread mysqlclient dl z) +else() + target_link_libraries (pcb_parser2 Common xivdat libmysql zlib1) +endif() target_link_libraries(pcb_parser2 ${Boost_LIBRARIES} ${Boost_LIBRARIES}) diff --git a/src/tools/pcb_reader/main.cpp b/src/tools/pcb_reader/main.cpp index 52b2686a..d3372689 100644 --- a/src/tools/pcb_reader/main.cpp +++ b/src/tools/pcb_reader/main.cpp @@ -6,6 +6,13 @@ #include "pcb.h" #include "lgb.h" +#include +#include +#include +#include +#include +#include + #include namespace fs = std::experimental::filesystem; @@ -74,7 +81,7 @@ int parseBlockEntry( char* data, std::vector& entries, int gOff if( block_entry.header.num_indices != 0 ) { block_entry.data.indices.resize( block_entry.header.num_indices ); - int32_t size_indexbuffer = block_entry.header.num_indices * 6; + int32_t size_indexbuffer = block_entry.header.num_indices * 12; memcpy( &block_entry.data.indices[0], data + doffset, size_indexbuffer ); doffset += size_indexbuffer; } @@ -100,9 +107,10 @@ void toFile(const std::string& fileName, const std::vector& vertices, cons { fprintf(fp_out, "v %f %f %f\n", v.x, v.y, v.z); } - for (auto i = 2002; i < indices.size(); i += 3) + for (auto i = 0; i < indices.size(); i += 3) { - fprintf(fp_out, "f %i %i %i\n", indices[i], indices[i + 1], indices[i + 2]); + //if( indices[i]!= 0 || indices[i + 1] != 0 || indices[i+ 2] != 0) + fprintf(fp_out, "f %i %i %i\n", indices[i] + 1, indices[i + 1] + 1, indices[i + 2] + 1); } fclose(fp_out); } @@ -110,7 +118,169 @@ void toFile(const std::string& fileName, const std::vector& vertices, cons int main() { + + xiv::dat::GameData data1( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" ); + xiv::exd::ExdData eData( data1 ); + + const xiv::dat::Cat& test = data1.get_category( "bg" ); + + auto &test_file = data1.get_file( "bg/ffxiv/sea_s1/fld/s1f5/level/bg.lgb" ); + auto §ion = test_file->access_data_sections().at( 0 ); + int32_t list_offset = *( uint32_t* ) §ion[0x18]; + int32_t size = *( uint32_t* ) §ion[4]; + + std::vector stringList; + + uint32_t offset = list_offset + 0x14; + + for( ; ; ) + { + std::string entry( §ion[offset] ); + offset += entry.size() + 1; + if( entry.find( "bgcommon" ) == std::string::npos && entry.find( ".mdl" ) == std::string::npos && entry.find( ".pcb" ) != std::string::npos ) + { + //stringList.push_back( entry ); + } + + if( offset >= size ) + { + break; + } + } + + auto &test_file1 = data1.get_file( "bg/ffxiv/roc_r1/fld/r1f1/collision/list.pcb" ); + auto §ion1 = test_file1->access_data_sections().at( 0 ); + std::string path = "bg/ffxiv/roc_r1/fld/r1f1/collision/"; + int offset1 = 0x20; + for( ; ; ) + { + + uint16_t trId = *( uint16_t* ) §ion1[offset1]; + + char someString[200]; + sprintf( someString, "%str%04d.pcb", path.c_str(), trId ); + stringList.push_back( std::string( someString ) ); + std::cout << someString << "\n"; + offset1 += 0x20; + + if( offset1 >= section1.size() ) + { + break; + } + } + + int total_vertices = 0; + int total_indices = 0; + int max_index = 0; + + std::vector vertices; + std::vector indices; + char *data; + int counter = 0; + for( auto fileName : stringList ) + { + std::cout << fileName << " "; + auto file = data1.get_file( fileName ); + auto sections = file->get_data_sections(); + + auto dataSection = sections[0]; + + std::cout << sections.size() << "\n"; + + + /*if( fileName != "collision1\\s1fa_t1_hasi1.pcb" ) + { + std::cout << fileName; + continue; + }*/ + + uint32_t offset = 0; + + PCB_FILE pcb_file; + memcpy( &pcb_file.header, &dataSection[0], sizeof( pcb_file.header ) ); + offset += sizeof( pcb_file.header ); + + std::vector entries; + + bool isgroup = true; + while( isgroup ) + { + PCB_BLOCK_ENTRY block_entry; + memcpy( &block_entry.header, &dataSection[0] + offset, sizeof( block_entry.header ) ); + isgroup = block_entry.header.type == 0x30 ? true : false; + + //printf( "BLOCKHEADER_%X: type: %i, group_size: %i\n", offset, block_entry.header.type, block_entry.header.group_size ); + // + if( isgroup ) + { + parseBlockEntry( &dataSection[0] + offset + 0x30, pcb_file.entries, offset ); + offset += block_entry.header.group_size; + } + else + { + parseBlockEntry( &dataSection[0] + offset, pcb_file.entries, offset ); + } + + } + + + for( auto &entry : pcb_file.entries ) + { + total_vertices += entry.header.num_vertices; + total_vertices += entry.header.num_v16; + + total_indices += entry.header.num_indices; + + for( auto &vertex_list : entry.data.vertices ) + { + vec3 v; + v.x = vertex_list.x; + v.y = vertex_list.y; + v.z = vertex_list.z; + vertices.push_back( v ); + } + + float x_base = abs( float( entry.header.x1 - entry.header.x ) ); + float y_base = abs( float( entry.header.y1 - entry.header.y ) ); + float z_base = abs( float( entry.header.z1 - entry.header.z ) ); + + for( const auto &link : entry.data.vertices_i16 ) + { + vec3 v(float( link.x ) / 0xFFFF, float( link.y ) / 0xFFFF, float( link.z ) / 0xFFFF); + + float x = float( link.x ); + float y = float( link.y ); + float z = float( link.z ); + v.x = ( x / 0xFFFF ) * x_base + entry.header.x; + v.y = ( y / 0xFFFF ) * y_base + entry.header.y; + v.z = ( z / 0xFFFF ) * z_base + entry.header.z; + vertices.push_back( v ); + } + + + for( const auto &index : entry.data.indices ) + { + //if( index.index[0] != 0 || index.index[1] != 0 || index.index[2] != 0 ) + { + indices.push_back(int(index.index[0]) + max_index ); + indices.push_back(int(index.index[1]) + max_index ); + indices.push_back(int(index.index[2]) + max_index ); + } + //std::cout << std::to_string( index.unknown[0] )<< " " << std::to_string( index.unknown[1] )<< " " << std::to_string( index.unknown[2]) << std::endl; + } + max_index = vertices.size(); + } + //for( auto block : pcb_file.entries ) + //{ + // auto pMesh3 = createBoundMeshFromPcbBlock( block ); + // if( pMesh3 ) + // m_pMeshList3.push_back( pMesh3 ); + //} + + } + toFile("test.obj", vertices, indices); + /* char *data; uint32_t offset = 0; //r1f1_b1_dor00.pcb @@ -178,12 +348,33 @@ int main() auto offset = sizeof(pcb_file.header); try { - parseBlockEntry(data + offset, pcb_file.entries, offset); + bool isgroup = true; + while( isgroup ) + { + PCB_BLOCK_ENTRY block_entry; + memcpy(&block_entry.header, data + offset, sizeof(block_entry.header)); + isgroup = block_entry.header.type == 0x30 ? true : false; + + //printf( "BLOCKHEADER_%X: type: %i, group_size: %i\n", offset, block_entry.header.type, block_entry.header.group_size ); + // + if( isgroup ) + { + std::cout << "ISGROUP" << "\n"; + parseBlockEntry(data + offset + 0x30, pcb_file.entries, offset); + offset += block_entry.header.group_size; + } + else + { + parseBlockEntry(data + offset, pcb_file.entries, offset); + } + } } catch(std::exception& e) { std::cout << "Unable to parse " << filename << " " << e.what() << "\n"; } + + } else { @@ -196,15 +387,7 @@ int main() total_vertices += entry.header.num_v16; total_indices += entry.header.num_indices; - /* - const auto& translationVec = pBgParts->header.translation; - const auto& rotationVec = pBgParts->header.rotation; - const auto& scaleVec = pBgParts->header.scale; - auto xrot = matrix4::rotateX(rotationVec.x); - auto yrot = matrix4::rotateY(rotationVec.y); - auto zrot = matrix4::rotateZ(rotationVec.z); - */ for( auto &vertex_list : entry.data.vertices ) { vec3 v; @@ -247,6 +430,6 @@ int main() } } toFile("test.obj", vertices, indices); - std::cout << "vertices " << vertices.size() << " indices " << indices.size() / 3 << " expected indices " << vertices.size() << " total " << total_indices << "\n"; + std::cout << "vertices " << vertices.size() << " indices " << indices.size() / 3 << " expected indices " << vertices.size() << " total " << total_indices << "\n";*/ return 0; } \ No newline at end of file diff --git a/src/tools/pcb_reader/pcb.h b/src/tools/pcb_reader/pcb.h index 165d7f7e..b8f451a9 100644 --- a/src/tools/pcb_reader/pcb.h +++ b/src/tools/pcb_reader/pcb.h @@ -43,6 +43,7 @@ struct PCB_INDEXDATA { uint8_t index[3]; uint8_t unknown[3]; + uint8_t unknown1[6]; }; struct PCB_VERTEXDATAI16