@@ -223,8 +223,9 @@ std::optional<int32_t> Satisfactory3DMap::ModelManager::findPakModel(const std::
223223 if (!className.starts_with (" /Game/FactoryGame/Buildable/" )) {
224224 return std::nullopt ;
225225 }
226- // TODO for now only buildings
227- if (!className.starts_with (" /Game/FactoryGame/Buildable/Building/" )) {
226+ // TODO for now only buildings and factories
227+ if (!className.starts_with (" /Game/FactoryGame/Buildable/Building/" ) &&
228+ !className.starts_with (" /Game/FactoryGame/Buildable/Factory/" )) {
228229 return std::nullopt ;
229230 }
230231
@@ -267,6 +268,9 @@ std::size_t Satisfactory3DMap::ModelManager::loadAsset(const std::string& classN
267268 }
268269
269270 std::optional<MeshModel> model;
271+ if (!model.has_value ()) {
272+ model = tryReadHardcodedMeshList (className);
273+ }
270274 if (!model.has_value ()) {
271275 model = tryReadInstanceDataCDO (asset, *defaultObject);
272276 }
@@ -283,6 +287,97 @@ std::size_t Satisfactory3DMap::ModelManager::loadAsset(const std::string& classN
283287 throw std::runtime_error (" No mesh found: " + className);
284288}
285289
290+ std::optional<Satisfactory3DMap::ModelManager::MeshModel> Satisfactory3DMap::ModelManager::tryReadHardcodedMeshList (
291+ const std::string& className) {
292+ static std::unordered_map<std::string, std::vector<std::pair<std::string, uint64_t >>> meshList{
293+ {
294+ " /Game/FactoryGame/Buildable/Factory/ConstructorMk1/Build_ConstructorMk1.Build_ConstructorMk1_C" ,
295+ {
296+ {" /Game/FactoryGame/Buildable/Factory/ConstructorMk1/Mesh/ConstructorMk1_static" ,
297+ 17531475687992568172u },
298+ {" /Game/FactoryGame/Buildable/Factory/ConstructorMk1/Mesh/SM_VAT_Constructor_MK1" ,
299+ 8788781691149688441u },
300+ },
301+ },
302+ {
303+ " /Game/FactoryGame/Buildable/Factory/AssemblerMk1/Build_AssemblerMk1.Build_AssemblerMk1_C" ,
304+ {
305+ {" /Game/FactoryGame/Buildable/Factory/AssemblerMk1/Mesh/AssemblerMk1_static" , 2876686963785518280u },
306+ {" /Game/FactoryGame/Buildable/Factory/AssemblerMk1/Mesh/SM_Assembler_VAT" , 1601938478383505850u },
307+ },
308+ },
309+ {
310+ " /Game/FactoryGame/Buildable/Factory/ManufacturerMk1/Build_ManufacturerMk1.Build_ManufacturerMk1_C" ,
311+ {
312+ {" /Game/FactoryGame/Buildable/Factory/ManufacturerMk1/Mesh/SM_Manufacturer" , 16596215462250294140u },
313+ {" /Game/FactoryGame/Buildable/Factory/ManufacturerMk1/Mesh/SM_VAT_Manufacturer" , 6258458244933010946u },
314+ },
315+ },
316+ {
317+ " /Game/FactoryGame/Buildable/Factory/Packager/Build_Packager.Build_Packager_C" ,
318+ {
319+ {" /Game/FactoryGame/Buildable/Factory/Packager/Mesh/SM_Packager_01" , 3412523861746888800u },
320+
321+ },
322+ },
323+ {
324+ " /Game/FactoryGame/Buildable/Factory/OilRefinery/Build_OilRefinery.Build_OilRefinery_C" ,
325+ {
326+ {" /Game/FactoryGame/Buildable/Factory/OilRefinery/Mesh/SM_OilRefinery_01" , 3116309774917793760u },
327+ {" /Game/FactoryGame/Buildable/Factory/OilRefinery/Mesh/SM_Refinery_VAT_01" , 15001394164382916637u },
328+ },
329+ },
330+ {
331+ " /Game/FactoryGame/Buildable/Factory/Blender/Build_Blender.Build_Blender_C" ,
332+ {
333+ {" /Game/FactoryGame/Buildable/Factory/Blender/Mesh/SM_Blender_01" , 1455697199552998628u },
334+ {" /Game/FactoryGame/Buildable/Factory/Blender/Mesh/SM_Blender_Mixer_01" , 6028939070185310187u },
335+ {" /Game/FactoryGame/Buildable/Factory/Blender/Mesh/SM_Blender_VAT" , 10110221954603884013u },
336+ },
337+ },
338+ {
339+ " /Game/FactoryGame/Buildable/Factory/HadronCollider/Build_HadronCollider.Build_HadronCollider_C" ,
340+ {
341+ {" /Game/FactoryGame/Buildable/Factory/HadronCollider/Mesh/SM_HadronCollider_01" , 685014826575293139u },
342+ {" /Game/FactoryGame/Buildable/Factory/HadronCollider/Mesh/SM_HC_Spool_01" , 17213070446062009596u },
343+ {" /Game/FactoryGame/Buildable/Factory/HadronCollider/Mesh/SM_HC_Spool_02" , 14653539250387620066u },
344+ },
345+ },
346+ {
347+ " /Game/FactoryGame/Buildable/Factory/QuantumEncoder/Build_QuantumEncoder.Build_QuantumEncoder_C" ,
348+ {
349+ {" /Game/FactoryGame/Buildable/Factory/QuantumEncoder/Mesh/SM_QuantumEncoder_01" , 14287920513212878460u },
350+
351+ },
352+ },
353+ {
354+ " /Game/FactoryGame/Buildable/Factory/Converter/Build_Converter.Build_Converter_C" ,
355+ {
356+ {" /Game/FactoryGame/Buildable/Factory/Converter/Mesh/SM_Converter_01" , 5689439705689270845u },
357+ {" /Game/FactoryGame/Buildable/Factory/Converter/Mesh/SM_VAT_Converter" , 10505819839463466523u },
358+ },
359+ },
360+ };
361+
362+ auto it = meshList.find (className);
363+ if (it == meshList.end ()) {
364+ return std::nullopt ;
365+ }
366+
367+ MeshModel model;
368+ model.reserve (it->second .size ());
369+ for (const auto & [packageName, publicExportHash] : it->second ) {
370+ // Try catch for logging, errors on hardcoded paths should be visible in log.
371+ try {
372+ model.push_back ({meshManager_->loadMesh (packageName, publicExportHash), glm::mat4 (1 .0f )});
373+ } catch (const std::exception& ex) {
374+ spdlog::error (" Error reading hard-coded mesh: {}" , ex.what ());
375+ throw ;
376+ }
377+ }
378+ return model;
379+ }
380+
286381std::optional<Satisfactory3DMap::ModelManager::MeshModel> Satisfactory3DMap::ModelManager::tryReadInstanceDataCDO (
287382 s::AssetFile& asset, const s::AssetExport& defaultObject) {
288383 try {
0 commit comments