mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-05 18:27:47 +00:00
pcb_reader things because lets use two threads and keep one locked for no reason
This commit is contained in:
parent
2a7727ec51
commit
249ed527f3
3 changed files with 164 additions and 96 deletions
|
@ -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/
|
||||||
|
|
|
@ -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 );
|
||||||
|
while( exportedGroups.empty() )
|
||||||
{
|
{
|
||||||
if( !exportedGroups.empty() )
|
cv.wait( lk );
|
||||||
|
}
|
||||||
|
|
||||||
|
//if( !exportedGroups.empty() )
|
||||||
{
|
{
|
||||||
auto& currFile = exportedGroups.front();
|
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;
|
|
||||||
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,11 +505,14 @@ int main( int argc, char* argv[] )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if( !noObj )
|
||||||
|
{
|
||||||
for( const auto& fileName : stringList )
|
for( const auto& fileName : stringList )
|
||||||
{
|
{
|
||||||
loadPcbFile( fileName );
|
loadPcbFile( fileName );
|
||||||
writeToFile( pcbFiles[ fileName ], fileName, zoneName );
|
writeToFile( pcbFiles[ fileName ], fileName, zoneName );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "[Info] " << "Writing obj file " << "\n";
|
std::cout << "[Info] " << "Writing obj file " << "\n";
|
||||||
uint32_t totalGroups = 0;
|
uint32_t totalGroups = 0;
|
||||||
|
@ -481,21 +524,22 @@ 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" );
|
||||||
|
totalGroups++;
|
||||||
|
|
||||||
|
if( !noObj )
|
||||||
|
{
|
||||||
fp_out = fopen( outfile_name.c_str(), "w" );
|
fp_out = fopen( outfile_name.c_str(), "w" );
|
||||||
if( fp_out )
|
if( fp_out )
|
||||||
{
|
{
|
||||||
|
// blank otherwise recast tries to load them..
|
||||||
fprintf( fp_out, "" );
|
fprintf( fp_out, "" );
|
||||||
fclose( fp_out );
|
fclose( fp_out );
|
||||||
fp_out = fopen( outfile_name.c_str(), "ab+" );
|
fp_out = fopen( outfile_name.c_str(), "ab+" );
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
|
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
|
||||||
totalGroups++;
|
|
||||||
for( const auto& pEntry : group.entries )
|
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( "" );
|
std::string fileName( "" );
|
||||||
fileName.resize( 256 );
|
fileName.resize( 256 );
|
||||||
totalGroupEntries++;
|
totalGroupEntries++;
|
||||||
|
@ -522,16 +566,21 @@ int main( int argc, char* argv[] )
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if( pBgParts )
|
switch( pEntry->getType() )
|
||||||
{
|
{
|
||||||
|
case LgbEntryType::BgParts:
|
||||||
|
{
|
||||||
|
auto pBgParts = static_cast< LGB_BGPARTS_ENTRY* >( pEntry.get() );
|
||||||
fileName = pBgParts->collisionFileName;
|
fileName = pBgParts->collisionFileName;
|
||||||
writeOutput( fileName, &pBgParts->header.scale, &pBgParts->header.rotation,
|
writeOutput( fileName, &pBgParts->header.scale, &pBgParts->header.rotation,
|
||||||
&pBgParts->header.translation );
|
&pBgParts->header.translation );
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// gimmick entry
|
// gimmick entry
|
||||||
if( pGimmick )
|
case LgbEntryType::Gimmick:
|
||||||
{
|
{
|
||||||
|
auto pGimmick = static_cast< LGB_GIMMICK_ENTRY* >( pEntry.get() );
|
||||||
{
|
{
|
||||||
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
|
const auto& it = sgbFiles.find( pGimmick->gimmickFileName );
|
||||||
if( it == sgbFiles.end() )
|
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 );
|
writeOutput( fileName, &pEntry->header.scale, &pEntry->header.rotation, &pEntry->header.translation );
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( generateNavmesh )
|
||||||
|
{
|
||||||
if( fp_out )
|
if( fp_out )
|
||||||
fclose( fp_out );
|
fclose( fp_out );
|
||||||
std::lock_guard< std::mutex > lock( navmeshMutex );
|
std::unique_lock lock( navmeshMutex );
|
||||||
exportedGroups.push( outfile_name );
|
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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue