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"
// garbage to skip model loading
extern bool ignoreModels;
extern bool noObj;
// all credit to
// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/

View file

@ -25,8 +25,10 @@
#include <ExdCat.h>
#include <Exd.h>
#include <condition_variable>
// garbage to ignore models
bool ignoreModels = false;
bool noObj = false;
std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
std::unordered_map< uint16_t, std::string > zoneNameMap;
@ -37,6 +39,7 @@ std::set< std::string > zoneDumpList;
xiv::dat::GameData* data1 = nullptr;
xiv::exd::ExdData* eData = nullptr;
enum class TerritoryTypeExdIndexes :
size_t
{
@ -173,11 +176,15 @@ void readFileToBuffer( const std::string& path, std::vector< char >& buf )
int main( int argc, char* argv[] )
{
auto startTime = std::chrono::system_clock::now();
auto entryStartTime = std::chrono::system_clock::now();
auto startTime = std::chrono::high_resolution_clock::now();
auto entryStartTime = std::chrono::high_resolution_clock::now();
std::condition_variable cv;
std::vector< std::string > argVec( argv + 1, argv + argc );
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 )
{ return arg == "--dump-all"; } ) != argVec.end();
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::queue< std::string > exportedGroups;
// todo:
#ifdef WIN32
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 )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
std::lock_guard< std::mutex > lock( navmeshMutex );
std::string currFile;
std::unique_lock lk( navmeshMutex );
while( exportedGroups.empty() )
{
if( !exportedGroups.empty() )
cv.wait( lk );
}
//if( !exportedGroups.empty() )
{
auto& currFile = exportedGroups.front();
std::cout << "\nGenerating navmesh for " << currFile << std::endl;
system( ( exportArg + currFile ).c_str() );
std::cout << "\nFinished generating navmesh for " << currFile << std::endl;
currFile = exportedGroups.front();
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();
LABEL_DUMP:
entryStartTime = std::chrono::system_clock::now();
entryStartTime = std::chrono::high_resolution_clock::now();
zoneName = *zoneDumpList.begin();
try
{
@ -286,13 +322,13 @@ int main( int argc, char* argv[] )
uint32_t max_index = 0;
// 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 )
{
fprintf( fp_out, "\n" );
fclose( fp_out );
}
else if( !ignoreModels )
else if( !noObj )
{
std::string errorMessage( "Cannot create " + zoneName + ".obj\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;
}
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, SGB_FILE > sgbFiles;
std::map< std::string, uint32_t > objCount;
auto loadPcbFile = [ & ]( const std::string& fileName )->bool
{
if( ignoreModels )
if( noObj )
return false;
try
{
if( fileName.find( '.' ) == std::string::npos )
@ -388,6 +425,9 @@ int main( int argc, char* argv[] )
const vec3* translation = nullptr,
const SGB_MODEL_ENTRY* pSgbEntry = nullptr )
{
if( noObj )
return;
char name2[0x100];
memset( name2, 0, 0x100 );
sprintf( &name2[ 0 ], "%s_%u", &name[ 0 ], objCount[ name ]++ );
@ -465,11 +505,14 @@ int main( int argc, char* argv[] )
}
};
if( !noObj )
{
for( const auto& fileName : stringList )
{
loadPcbFile( fileName );
writeToFile( pcbFiles[ fileName ], fileName, zoneName );
}
}
std::cout << "[Info] " << "Writing obj file " << "\n";
uint32_t totalGroups = 0;
@ -481,21 +524,22 @@ int main( int argc, char* argv[] )
{
max_index = 0;
std::string outfile_name( zoneName + "_" + group.name + ".obj" );
totalGroups++;
if( !noObj )
{
fp_out = fopen( outfile_name.c_str(), "w" );
if( fp_out )
{
// blank otherwise recast tries to load them..
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++;
for( const auto& pEntry : group.entries )
{
auto pGimmick = dynamic_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() );
auto pBgParts = dynamic_cast< LGB_BGPARTS_ENTRY* >( pEntry.get() );
std::string fileName( "" );
fileName.resize( 256 );
totalGroupEntries++;
@ -522,16 +566,21 @@ int main( int argc, char* argv[] )
return true;
};
if( pBgParts )
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
if( pGimmick )
case LgbEntryType::Gimmick:
{
auto pGimmick = static_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() );
{
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
if( it == sgbFiles.end() )
@ -557,23 +606,31 @@ int main( int argc, char* argv[] )
}
}
if( pEntry->getType() == LgbEntryType::EventObject )
case LgbEntryType::EventObject:
{
writeOutput( fileName, &pEntry->header.scale, &pEntry->header.rotation, &pEntry->header.translation );
}
break;
}
}
}
if( generateNavmesh )
{
if( fp_out )
fclose( fp_out );
std::lock_guard< std::mutex > lock( navmeshMutex );
std::unique_lock lock( navmeshMutex );
exportedGroups.push( outfile_name );
cv.notify_one();
}
}
}
std::cout << "[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n";
std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n";
}
std::cout << "[Success] " << "Exported " << zoneName << " in " <<
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 )
{
@ -587,11 +644,22 @@ int main( int argc, char* argv[] )
std::cout << "\n\n\n";
LABEL_NEXT_ZONE_ENTRY:
zoneDumpList.erase( zoneName );
if( !zoneDumpList.empty() )
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::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";
getchar();

View file

@ -12,7 +12,7 @@
#include "vec3.h"
// 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