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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; };
|
||||
|
||||
Reference in New Issue
Block a user