1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-05 10:17:46 +00:00

pcb_reader things because lets use two threads and keep one locked for no reason

This commit is contained in:
Tahir Akhlaq 2019-01-19 18:46:21 +00:00
parent 2a7727ec51
commit 249ed527f3
3 changed files with 164 additions and 96 deletions

View file

@ -14,7 +14,7 @@
#include "sgb.h" #include "sgb.h"
// garbage to skip model loading // garbage to skip model loading
extern bool ignoreModels; extern bool noObj;
// all credit to // all credit to
// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/ // https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/

View file

@ -25,8 +25,10 @@
#include <ExdCat.h> #include <ExdCat.h>
#include <Exd.h> #include <Exd.h>
#include <condition_variable>
// garbage to ignore models // garbage to ignore models
bool ignoreModels = false; bool noObj = false;
std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" ); std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::unordered_map< uint16_t, std::string > zoneNameMap; std::unordered_map< uint16_t, std::string > zoneNameMap;
@ -37,6 +39,7 @@ std::set< std::string > zoneDumpList;
xiv::dat::GameData* data1 = nullptr; xiv::dat::GameData* data1 = nullptr;
xiv::exd::ExdData* eData = nullptr; xiv::exd::ExdData* eData = nullptr;
enum class TerritoryTypeExdIndexes : enum class TerritoryTypeExdIndexes :
size_t size_t
{ {
@ -173,11 +176,15 @@ void readFileToBuffer( const std::string& path, std::vector< char >& buf )
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
auto startTime = std::chrono::system_clock::now(); auto startTime = std::chrono::high_resolution_clock::now();
auto entryStartTime = std::chrono::system_clock::now(); auto entryStartTime = std::chrono::high_resolution_clock::now();
std::condition_variable cv;
std::vector< std::string > argVec( argv + 1, argv + argc ); std::vector< std::string > argVec( argv + 1, argv + argc );
std::string zoneName = "r2t2"; std::string zoneName = "r2t2";
noObj = std::remove_if( argVec.begin(), argVec.end(), []( auto arg )
{ return arg == "--no-obj"; } ) != argVec.end();
bool dumpAllZones = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) bool dumpAllZones = std::remove_if( argVec.begin(), argVec.end(), []( auto arg )
{ return arg == "--dump-all"; } ) != argVec.end(); { return arg == "--dump-all"; } ) != argVec.end();
bool generateNavmesh = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) bool generateNavmesh = std::remove_if( argVec.begin(), argVec.end(), []( auto arg )
@ -210,29 +217,58 @@ int main( int argc, char* argv[] )
std::mutex navmeshMutex; std::mutex navmeshMutex;
std::queue< std::string > exportedGroups; std::queue< std::string > exportedGroups;
// todo:
#ifdef WIN32
std::string exportArg( "RecastDemo.exe --type tileMesh --obj " ); std::string exportArg( "RecastDemo.exe --type tileMesh --obj " );
std::thread navmeshThread( [&navmeshMutex, &exportedGroups, &exportArg, &generateNavmesh]() #else
std::string exportArg( "./RecastDemo --type tileMesh --obj ");
#endif
std::thread navmeshThread( [&navmeshMutex, &exportedGroups, &exportArg, &generateNavmesh, &cv]()
{ {
while( generateNavmesh ) while( generateNavmesh )
{ {
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); std::string currFile;
std::lock_guard< std::mutex > lock( navmeshMutex );
{ std::unique_lock lk( navmeshMutex );
if( !exportedGroups.empty() ) while( exportedGroups.empty() )
{ {
auto& currFile = exportedGroups.front(); cv.wait( lk );
std::cout << "\nGenerating navmesh for " << currFile << std::endl; }
system( ( exportArg + currFile ).c_str() );
std::cout << "\nFinished generating navmesh for " << currFile << std::endl; //if( !exportedGroups.empty() )
{
currFile = exportedGroups.front();
exportedGroups.pop(); exportedGroups.pop();
} }
if( !currFile.empty() )
{
std::error_code e;
if( std::experimental::filesystem::exists( currFile ) && std::experimental::filesystem::file_size( currFile, e ) > 1024 )
{
std::string generateMessage( "\nGenerating navmesh for " + currFile + "\n" );
std::cout << generateMessage << std::endl;
auto start = std::chrono::high_resolution_clock::now();
system( ( exportArg + currFile ).c_str() );
std::string finishMessage( "\nFinished generating navmesh for " + currFile + " in " +
std::to_string( std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - start ).count() ) + " seconds\n" );
std::cout << finishMessage << std::endl;
}
else
{
std::cout << ( std::string( "Unable to load OBJ file for " ) + currFile + "\n" ) << std::endl;
}
} }
} }
}); });
navmeshThread.detach(); navmeshThread.detach();
LABEL_DUMP: LABEL_DUMP:
entryStartTime = std::chrono::system_clock::now(); entryStartTime = std::chrono::high_resolution_clock::now();
zoneName = *zoneDumpList.begin(); zoneName = *zoneDumpList.begin();
try try
{ {
@ -286,13 +322,13 @@ int main( int argc, char* argv[] )
uint32_t max_index = 0; uint32_t max_index = 0;
// dont bother if we cant write to a file // dont bother if we cant write to a file
auto fp_out = ignoreModels ? ( FILE* ) nullptr : fopen( ( zoneName + ".obj" ).c_str(), "w" ); auto fp_out = noObj ? ( FILE* ) nullptr : fopen( ( zoneName + ".obj" ).c_str(), "w" );
if( fp_out ) if( fp_out )
{ {
fprintf( fp_out, "\n" ); fprintf( fp_out, "\n" );
fclose( fp_out ); fclose( fp_out );
} }
else if( !ignoreModels ) else if( !noObj )
{ {
std::string errorMessage( "Cannot create " + zoneName + ".obj\n" + std::string errorMessage( "Cannot create " + zoneName + ".obj\n" +
" Check no programs have a handle to file and run as admin.\n" ); " Check no programs have a handle to file and run as admin.\n" );
@ -301,15 +337,16 @@ int main( int argc, char* argv[] )
return 0; return 0;
} }
if( ignoreModels || ( fp_out = fopen( ( zoneName + ".obj" ).c_str(), "ab+" ) ) ) if( noObj || ( fp_out = fopen( ( zoneName + ".obj" ).c_str(), "ab+" ) ) )
{ {
std::map< std::string, PCB_FILE > pcbFiles; std::map< std::string, PCB_FILE > pcbFiles;
std::map< std::string, SGB_FILE > sgbFiles; std::map< std::string, SGB_FILE > sgbFiles;
std::map< std::string, uint32_t > objCount; std::map< std::string, uint32_t > objCount;
auto loadPcbFile = [ & ]( const std::string& fileName )->bool auto loadPcbFile = [ & ]( const std::string& fileName )->bool
{ {
if( ignoreModels ) if( noObj )
return false; return false;
try try
{ {
if( fileName.find( '.' ) == std::string::npos ) if( fileName.find( '.' ) == std::string::npos )
@ -388,6 +425,9 @@ int main( int argc, char* argv[] )
const vec3* translation = nullptr, const vec3* translation = nullptr,
const SGB_MODEL_ENTRY* pSgbEntry = nullptr ) const SGB_MODEL_ENTRY* pSgbEntry = nullptr )
{ {
if( noObj )
return;
char name2[0x100]; char name2[0x100];
memset( name2, 0, 0x100 ); memset( name2, 0, 0x100 );
sprintf( &name2[ 0 ], "%s_%u", &name[ 0 ], objCount[ name ]++ ); sprintf( &name2[ 0 ], "%s_%u", &name[ 0 ], objCount[ name ]++ );
@ -465,10 +505,13 @@ int main( int argc, char* argv[] )
} }
}; };
for( const auto& fileName : stringList ) if( !noObj )
{ {
loadPcbFile( fileName ); for( const auto& fileName : stringList )
writeToFile( pcbFiles[ fileName ], fileName, zoneName ); {
loadPcbFile( fileName );
writeToFile( pcbFiles[ fileName ], fileName, zoneName );
}
} }
std::cout << "[Info] " << "Writing obj file " << "\n"; std::cout << "[Info] " << "Writing obj file " << "\n";
@ -481,99 +524,113 @@ int main( int argc, char* argv[] )
{ {
max_index = 0; max_index = 0;
std::string outfile_name( zoneName + "_" + group.name + ".obj" ); std::string outfile_name( zoneName + "_" + group.name + ".obj" );
fp_out = fopen( outfile_name.c_str(), "w" );
if( fp_out )
{
fprintf( fp_out, "" );
fclose( fp_out );
fp_out = fopen( outfile_name.c_str(), "ab+" );
}
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
totalGroups++; totalGroups++;
for( const auto& pEntry : group.entries )
if( !noObj )
{ {
auto pGimmick = dynamic_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() ); fp_out = fopen( outfile_name.c_str(), "w" );
auto pBgParts = dynamic_cast< LGB_BGPARTS_ENTRY* >( pEntry.get() ); if( fp_out )
std::string fileName( "" );
fileName.resize( 256 );
totalGroupEntries++;
// write files
auto writeOutput = [ & ]( const std::string& fileName, const vec3* scale, const vec3* rotation,
const vec3* translation, const SGB_MODEL_ENTRY* pModel = nullptr )->bool
{ {
{ // blank otherwise recast tries to load them..
const auto& it = pcbFiles.find( fileName ); fprintf( fp_out, "" );
if( it == pcbFiles.end() ) fclose( fp_out );
{ fp_out = fopen( outfile_name.c_str(), "ab+" );
if( fileName.empty() || !loadPcbFile( fileName ) )
return false;
//std::cout << "\t\tLoaded PCB File " << pBgParts->collisionFileName << "\n";
}
}
const auto& it = pcbFiles.find( fileName );
if( it != pcbFiles.end() )
{
const auto& pcb_file = it->second;
writeToFile( pcb_file, fileName, group.name, scale, rotation, translation, pModel );
}
return true;
};
if( pBgParts )
{
fileName = pBgParts->collisionFileName;
writeOutput( fileName, &pBgParts->header.scale, &pBgParts->header.rotation,
&pBgParts->header.translation );
} }
// gimmick entry //std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
if( pGimmick ) for( const auto& pEntry : group.entries )
{ {
std::string fileName( "" );
fileName.resize( 256 );
totalGroupEntries++;
// write files
auto writeOutput = [ & ]( const std::string& fileName, const vec3* scale, const vec3* rotation,
const vec3* translation, const SGB_MODEL_ENTRY* pModel = nullptr )->bool
{ {
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
if( it == sgbFiles.end() )
{ {
// std::cout << "\tGIMMICK:\n\t\t" << pGimmick->gimmickFileName << "\n"; const auto& it = pcbFiles.find( fileName );
loadSgbFile( pGimmick->gimmickFileName ); if( it == pcbFiles.end() )
}
}
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
if( it != sgbFiles.end() )
{
const auto& sgbFile = it->second;
for( const auto& group : sgbFile.entries )
{
for( const auto& pEntry : group.entries )
{ {
auto pModel = dynamic_cast< SGB_MODEL_ENTRY* >( pEntry.get() ); if( fileName.empty() || !loadPcbFile( fileName ) )
fileName = pModel->collisionFileName; return false;
writeOutput( fileName, &pGimmick->header.scale, &pGimmick->header.rotation, //std::cout << "\t\tLoaded PCB File " << pBgParts->collisionFileName << "\n";
&pGimmick->header.translation, pModel );
} }
} }
const auto& it = pcbFiles.find( fileName );
if( it != pcbFiles.end() )
{
const auto& pcb_file = it->second;
writeToFile( pcb_file, fileName, group.name, scale, rotation, translation, pModel );
}
return true;
};
switch( pEntry->getType() )
{
case LgbEntryType::BgParts:
{
auto pBgParts = static_cast< LGB_BGPARTS_ENTRY* >( pEntry.get() );
fileName = pBgParts->collisionFileName;
writeOutput( fileName, &pBgParts->header.scale, &pBgParts->header.rotation,
&pBgParts->header.translation );
}
break;
// gimmick entry
case LgbEntryType::Gimmick:
{
auto pGimmick = static_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() );
{
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
if( it == sgbFiles.end() )
{
// std::cout << "\tGIMMICK:\n\t\t" << pGimmick->gimmickFileName << "\n";
loadSgbFile( pGimmick->gimmickFileName );
}
}
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
if( it != sgbFiles.end() )
{
const auto& sgbFile = it->second;
for( const auto& group : sgbFile.entries )
{
for( const auto& pEntry : group.entries )
{
auto pModel = dynamic_cast< SGB_MODEL_ENTRY* >( pEntry.get() );
fileName = pModel->collisionFileName;
writeOutput( fileName, &pGimmick->header.scale, &pGimmick->header.rotation,
&pGimmick->header.translation, pModel );
}
}
}
}
case LgbEntryType::EventObject:
{
writeOutput( fileName, &pEntry->header.scale, &pEntry->header.rotation, &pEntry->header.translation );
}
break;
} }
} }
if( pEntry->getType() == LgbEntryType::EventObject )
{
writeOutput( fileName, &pEntry->header.scale, &pEntry->header.rotation, &pEntry->header.translation );
}
} }
if( fp_out ) if( generateNavmesh )
fclose( fp_out ); {
std::lock_guard< std::mutex > lock( navmeshMutex ); if( fp_out )
exportedGroups.push( outfile_name ); fclose( fp_out );
std::unique_lock lock( navmeshMutex );
exportedGroups.push( outfile_name );
cv.notify_one();
}
} }
} }
std::cout << "[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n"; std::cout << "[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n";
std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n"; std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n";
} }
std::cout << "[Success] " << "Exported " << zoneName << " in " << std::cout << "[Success] " << "Exported " << zoneName << " in " <<
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::duration_cast< std::chrono::seconds >(
std::chrono::system_clock::now() - entryStartTime ).count() << " seconds\n"; std::chrono::high_resolution_clock::now() - entryStartTime ).count() << " seconds\n";
} }
catch( std::exception& e ) catch( std::exception& e )
{ {
@ -587,11 +644,22 @@ int main( int argc, char* argv[] )
std::cout << "\n\n\n"; std::cout << "\n\n\n";
LABEL_NEXT_ZONE_ENTRY: LABEL_NEXT_ZONE_ENTRY:
zoneDumpList.erase( zoneName ); zoneDumpList.erase( zoneName );
if( !zoneDumpList.empty() ) if( !zoneDumpList.empty() )
goto LABEL_DUMP; goto LABEL_DUMP;
while( 1 )
{
std::lock_guard< std::mutex > lock( navmeshMutex );
if( exportedGroups.empty() )
generateNavmesh = false;
if( navmeshThread.joinable() )
navmeshThread.join();
std::this_thread::sleep_for( 1s );
}
std::cout << "\n\n\n[Success] Finished all tasks in " << std::cout << "\n\n\n[Success] Finished all tasks in " <<
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count() std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count()
<< " seconds\n"; << " seconds\n";
getchar(); getchar();

View file

@ -12,7 +12,7 @@
#include "vec3.h" #include "vec3.h"
// garbage to skip model loading // garbage to skip model loading
extern bool ignoreModels; extern bool noObj;
// //
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs // ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs