16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 04:39:18 +02:00

async mesh loading

This commit is contained in:
maj00r
2026-06-16 01:04:37 +02:00
parent 2f90246907
commit 9574d2051b
35 changed files with 3239 additions and 859 deletions

View File

@@ -14,7 +14,9 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "model/AnimModel.h"
#include "scene/eu7/eu7_model_prefetch.h"
#include <mutex>
#include <unordered_map>
#include "scene/eu7/eu7_pack_bench.h"
@@ -390,6 +392,7 @@ TAnimModel::reset_pack_for_insert( scene::node_data const &nodedata ) {
pModel = nullptr;
m_eu7_pack = false;
m_instanceable = false;
m_pack_cell_id = 255;
m_materialdata = {};
asText.clear();
}
@@ -612,10 +615,12 @@ namespace eu7_pack_cache {
enum class slot_t : std::int8_t { unknown = -1, no = 0, yes = 1 };
std::mutex g_mutex;
std::unordered_map<TModel3d const *, slot_t> g_model;
[[nodiscard]] bool
lookup( TModel3d *const model, bool &instanceable ) {
std::lock_guard<std::mutex> lock { g_mutex };
auto const it { g_model.find( model ) };
if( it == g_model.end() || it->second == slot_t::unknown ) {
return false;
@@ -626,6 +631,7 @@ lookup( TModel3d *const model, bool &instanceable ) {
void
store( TModel3d *const model, bool const instanceable ) {
std::lock_guard<std::mutex> lock { g_mutex };
g_model[ model ] = instanceable ? slot_t::yes : slot_t::no;
}
@@ -634,11 +640,13 @@ warm( TModel3d *const model ) {
if( model == nullptr ) {
return;
}
std::lock_guard<std::mutex> lock { g_mutex };
auto const it { g_model.find( model ) };
if( it != g_model.end() && it->second != slot_t::unknown ) {
return;
}
store( model, false == submodel_tree_blocks_instancing( model->Root ) );
g_model[ model ] =
false == submodel_tree_blocks_instancing( model->Root ) ? slot_t::yes : slot_t::no;
}
} // namespace eu7_pack_cache
@@ -659,7 +667,11 @@ TAnimModel::warm_instanceable_cache( TModel3d *const model ) {
bool
TAnimModel::LoadEu7PackWarm(
TModel3d *const mesh,
std::string const &texture_file ) {
std::string const &texture_file,
std::string const &model_file,
std::string const &resolved_texture,
std::uint32_t const textures_alpha,
bool const instanceable_hint ) {
pModel = mesh;
if( mesh == nullptr ) {
return true;
@@ -680,16 +692,27 @@ TAnimModel::LoadEu7PackWarm(
false == normalized.ends_with( '/' ) &&
normalized.find( "tr/none" ) == std::string::npos &&
normalized.find( '#' ) == std::string::npos ) {
m_materialdata.assign( normalized );
if( m_materialdata.replacable_skins[ 1 ] == null_handle ) {
scene::eu7::pack_bench_inc( &scene::eu7::Eu7PackBench::main_texture_assign_fail );
scene::eu7::log_pack_texture_fail( normalized );
}
(void)scene::eu7::assign_pack_texture(
m_materialdata,
model_file,
normalized,
resolved_texture,
textures_alpha );
}
}
else if( textures_alpha != 0 ) {
m_materialdata.textures_alpha = static_cast<int>( textures_alpha );
}
m_eu7_pack = true;
if( instanceable_hint ) {
++s_classified_total;
m_instanceable = true;
++s_instanceable_total;
return true;
}
bool cached_instanceable { false };
if( anim_instancing_detail::eu7_pack_cache::lookup( mesh, cached_instanceable ) ) {
++s_classified_total;

View File

@@ -135,7 +135,11 @@ public:
// PACK stream: mesh pointer already resolved; skips GetModel lookup.
bool LoadEu7PackWarm(
TModel3d *Mesh,
std::string const &texture_file );
std::string const &texture_file,
std::string const &model_file = {},
std::string const &resolved_texture = {},
std::uint32_t textures_alpha = 0,
bool instanceable_hint = false );
void
reset_pack_for_insert( scene::node_data const &Nodedata );
static TAnimModel *
@@ -243,6 +247,7 @@ public:
// computed once at end of Load() so the renderer can simply test the flag.
bool m_instanceable { false };
bool m_eu7_pack { false };
std::uint8_t m_pack_cell_id { 255 };
// helper: evaluates current state and updates m_instanceable accordingly.
void update_instanceable_flag();

View File

@@ -21,6 +21,8 @@ http://mozilla.org/MPL/2.0/.
#include "utilities/Logs.h"
#include "utilities/utilities.h"
#include <memory>
// wczytanie modelu do kontenerka
TModel3d *
TMdlContainer::LoadModel(std::string const &Name, bool const Dynamic) {
@@ -132,6 +134,53 @@ TModelsManager::IsModelCached( std::string const &Name ) {
return find_in_databank( filename ).first;
}
[[nodiscard]] std::string
normalize_pack_model_key( std::string name ) {
erase_extension( name );
return ToLower( name );
}
std::pair<bool, TModel3d *>
TModelsManager::TryGetCachedModel( std::string const &Name ) {
return find_in_databank( normalize_pack_model_key( Name ) );
}
std::string
TModelsManager::ResolveModelDiskPath( std::string Name ) {
return find_on_disk( normalize_pack_model_key( std::move( Name ) ) );
}
std::shared_ptr<TModel3d>
TModelsManager::LoadModelCpuDeferred(
std::string const &DiskPath,
bool const Dynamic ) {
auto model { std::make_shared<TModel3d>() };
if( false == model->LoadFromFile( DiskPath, Dynamic, true ) ) {
return nullptr;
}
return model;
}
TModel3d *
TModelsManager::PublishLoadedModel(
std::string const &VirtualName,
std::shared_ptr<TModel3d> Model ) {
if( Model == nullptr ) {
return nullptr;
}
auto const lookup { find_in_databank( VirtualName ) };
if( lookup.first && lookup.second != nullptr ) {
return lookup.second;
}
Model->Init();
m_models.emplace_back();
m_models.back().Model = std::move( Model );
m_modelsmap.emplace( VirtualName, m_models.size() - 1 );
return m_models.back().Model.get();
}
std::pair<bool, TModel3d *>
TModelsManager::find_in_databank( std::string const &Name ) {

View File

@@ -10,6 +10,8 @@ http://mozilla.org/MPL/2.0/.
#include "utilities/Classes.h"
#include <memory>
class TMdlContainer {
friend class TModelsManager;
private:
@@ -24,6 +26,17 @@ public:
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
static TModel3d *GetModel(std::string const &Name, bool const dynamic = false, bool const Logerrors = true , int uid = 0);
[[nodiscard]] static bool IsModelCached( std::string const &Name );
// EU7 PACK stream: CPU parse on workers, GPU Init on main thread.
[[nodiscard]] static std::pair<bool, TModel3d *>
TryGetCachedModel( std::string const &Name );
[[nodiscard]] static std::string
ResolveModelDiskPath( std::string Name );
[[nodiscard]] static std::shared_ptr<TModel3d>
LoadModelCpuDeferred( std::string const &DiskPath, bool const Dynamic = false );
[[nodiscard]] static TModel3d *
PublishLoadedModel(
std::string const &VirtualName,
std::shared_ptr<TModel3d> Model );
private:
// types:

View File

@@ -1623,8 +1623,10 @@ glm::vec3 TSubModel::offset(float const Geometrytestoffsetthreshold) const
return offset;
}
bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
{
bool TModel3d::LoadFromFile(
std::string const &FileName,
bool const dynamic,
bool const defer_gpu_init ) {
// wczytanie modelu z pliku
/*
// NOTE: disabled, this work is now done by the model manager
@@ -1646,20 +1648,24 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
{
WriteLog("Forced loading text model \"" + name + ".t3d\"");
LoadFromTextFile(name + ".t3d", dynamic);
if (!dynamic)
if( false == defer_gpu_init && false == dynamic ) {
Init();
}
}
else if (FileExists(asBinary))
{
LoadFromBinFile(asBinary, dynamic);
asBinary = "";
Init();
if( false == defer_gpu_init ) {
Init();
}
}
else if (FileExists(name + ".t3d"))
{
LoadFromTextFile(name + ".t3d", dynamic);
if (!dynamic)
if( false == defer_gpu_init && false == dynamic ) {
Init();
}
}
bool const result = Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem

View File

@@ -289,7 +289,10 @@ public:
void AddTo(TSubModel *tmp, TSubModel *SubModel);
void LoadFromTextFile(std::string const &FileName, bool dynamic);
void LoadFromBinFile(std::string const &FileName, bool dynamic);
bool LoadFromFile(std::string const &FileName, bool dynamic);
bool LoadFromFile(
std::string const &FileName,
bool dynamic,
bool defer_gpu_init = false );
TSubModel *AppendChildFromGeometry(const std::string &name, const std::string &parent, const gfx::vertex_array &vertices, const gfx::index_array &indices);
void SaveToBinFile(std::string const &FileName);
uint32_t Flags() const { return iFlags; };