17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 05:09:20 +02:00

perf(models): replacable skins of scenery models located once for a skin name; light and season variant submodels located once for a model instead of for each instance

This commit is contained in:
2026-10-06 03:35:00 +02:00
parent 4eb14a9419
commit 3a05d0d649
3 changed files with 50 additions and 21 deletions

View File

@@ -257,7 +257,20 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
asText = asReplacableTexture.substr( 1, asReplacableTexture.length() - 1 ); // zapamiętanie tekstu
}
else if( asReplacableTexture != "none" ) {
m_materialdata.assign( asReplacableTexture );
// the same skin is typically shared by lots of instances, and locating its files takes a couple dozen disk lookups.
// NOTE: only located skins are kept, so a missing one is still searched for each time, the way it used to be
static std::unordered_map<std::string, material_data> skins;
auto const skinkey { Global.asCurrentTexturePath + '|' + asReplacableTexture };
auto const lookup { skins.find( skinkey ) };
if( lookup != skins.end() ) {
m_materialdata = lookup->second;
}
else {
m_materialdata.assign( asReplacableTexture );
if( m_materialdata.replacable_skins[ 1 ] != null_handle ) {
skins.emplace( skinkey, m_materialdata );
}
}
}
// TODO: redo the random timer initialization
@@ -304,26 +317,14 @@ bool TAnimModel::Load(cParser *parser, bool ter)
}
else
{ // wiązanie świateł, o ile model wczytany
LightsOn[0] = pModel->GetFromName("Light_On00");
LightsOn[1] = pModel->GetFromName("Light_On01");
LightsOn[2] = pModel->GetFromName("Light_On02");
LightsOn[3] = pModel->GetFromName("Light_On03");
LightsOn[4] = pModel->GetFromName("Light_On04");
LightsOn[5] = pModel->GetFromName("Light_On05");
LightsOn[6] = pModel->GetFromName("Light_On06");
LightsOn[7] = pModel->GetFromName("Light_On07");
LightsOff[0] = pModel->GetFromName("Light_Off00");
LightsOff[1] = pModel->GetFromName("Light_Off01");
LightsOff[2] = pModel->GetFromName("Light_Off02");
LightsOff[3] = pModel->GetFromName("Light_Off03");
LightsOff[4] = pModel->GetFromName("Light_Off04");
LightsOff[5] = pModel->GetFromName("Light_Off05");
LightsOff[6] = pModel->GetFromName("Light_Off06");
LightsOff[7] = pModel->GetFromName("Light_Off07");
sm_winter_variant = pModel->GetFromName("winter_variant");
sm_spring_variant = pModel->GetFromName("spring_variant");
sm_summer_variant = pModel->GetFromName("summer_variant");
sm_autumn_variant = pModel->GetFromName("autumn_variant");
// the submodels are located once for the model and shared by its instances
auto const &submodels { pModel->instance_parts() };
LightsOn = submodels.lights_on;
LightsOff = submodels.lights_off;
sm_winter_variant = submodels.variants[ 0 ];
sm_spring_variant = submodels.variants[ 1 ];
sm_summer_variant = submodels.variants[ 2 ];
sm_autumn_variant = submodels.variants[ 3 ];
}
for (int i = 0; i < iMaxNumLights; ++i)
if (LightsOn[i] || LightsOff[i]) // Ra: zlikwidowałem wymóg istnienia obu

View File

@@ -1567,6 +1567,23 @@ TSubModel *TModel3d::GetFromName(std::string const &Name) const
}
};
// returns submodels which scenery instances of the model refer to by name, locating them on first use
TModel3d::instance_submodels const &TModel3d::instance_parts()
{
if (false == m_instancesubmodelslocated)
{
for (std::size_t idx = 0; idx < m_instancesubmodels.lights_on.size(); ++idx)
{
auto const index{(idx < 10 ? "0" : "") + std::to_string(idx)};
m_instancesubmodels.lights_on[idx] = GetFromName("Light_On" + index);
m_instancesubmodels.lights_off[idx] = GetFromName("Light_Off" + index);
}
m_instancesubmodels.variants = {GetFromName("winter_variant"), GetFromName("spring_variant"), GetFromName("summer_variant"), GetFromName("autumn_variant")};
m_instancesubmodelslocated = true;
}
return m_instancesubmodels;
}
// locates particle source submodels and stores them on internal list
nameoffset_sequence const &TModel3d::find_smoke_sources()
{

View File

@@ -267,6 +267,12 @@ class TModel3d
friend opengl33_renderer;
public:
// submodels which scenery instances of the model refer to by name
struct instance_submodels {
std::array<TSubModel *, 8> lights_on {}; // Light_On00 - Light_On07
std::array<TSubModel *, 8> lights_off {}; // Light_Off00 - Light_Off07
std::array<TSubModel *, 4> variants {}; // winter_variant, spring_variant, summer_variant, autumn_variant
};
TSubModel *Root { nullptr }; // drzewo submodeli
uint32_t iFlags { 0 }; // Ra: czy submodele mają przezroczyste tekstury
public: // Ra: tymczasowo
@@ -281,6 +287,8 @@ private:
std::string asBinary; // nazwa pod którą zapisać model binarny
std::string m_filename;
nameoffset_sequence m_smokesources; // list of particle sources defined in the model
instance_submodels m_instancesubmodels; // filled on first use, see instance_parts()
bool m_instancesubmodelslocated { false };
public:
TModel3d() = default;
@@ -289,6 +297,9 @@ public:
return Root ? Root->m_boundingradius : 0.f; }
inline TSubModel * GetSMRoot() { return Root; };
TSubModel * GetFromName(std::string const &Name) const;
// returns submodels which scenery instances of the model refer to by name. the search for a name goes through the whole
// submodel tree, so it's done once for the model instead of once for each of its instances
instance_submodels const & instance_parts();
TSubModel * AddToNamed(const char *Name, TSubModel *SubModel);
nameoffset_sequence const & find_smoke_sources();
void AddTo(TSubModel *tmp, TSubModel *SubModel);