Skip to content

Commit

Permalink
Made 'managedmaterials' work with addon parts. ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
ohlidalp committed Oct 31, 2023
1 parent e135dfe commit 4315f1b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
14 changes: 10 additions & 4 deletions source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ void ActorSpawner::InitializeRig()

m_flex_factory.CheckAndLoadFlexbodyCache();

m_placeholder_managedmat = Ogre::MaterialManager::getSingleton().getByName("rigsofrods/managedmaterial-placeholder"); // Built-in
m_managedmat_placeholder_template = Ogre::MaterialManager::getSingleton().getByName("rigsofrods/managedmaterial-placeholder"); // Built-in

m_apply_simple_materials = App::diag_simple_materials->getBool();
if (m_apply_simple_materials)
Expand Down Expand Up @@ -1634,6 +1634,7 @@ void ActorSpawner::ProcessProp(RigDef::Prop & def)

prop.pp_scene_node = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode();
const std::string instance_name = this->ComposeName("PropEntity", prop_index);
LOG(fmt::format("[RoR] DBG ActorSpawner::ProcessProp(): creating MeshObject '{}' in RG '{}'", def.mesh_name, resource_group));
prop.pp_mesh_obj = new MeshObject(def.mesh_name, resource_group, instance_name, prop.pp_scene_node);

prop.pp_mesh_obj->setCastShadows(true); // Orig code {{ prop.pp_mesh_obj->setCastShadows(shadowmode != 0); }}, shadowmode has default value 1 and changes with undocumented directive 'set_shadows'
Expand Down Expand Up @@ -2291,7 +2292,7 @@ Ogre::MaterialPtr ActorSpawner::InstantiateManagedMaterial(Ogre::String const &
return Ogre::MaterialPtr();
}

return src_mat->clone(clone_name, true, m_custom_resource_group);
return src_mat->clone(clone_name);
}

void ActorSpawner::ProcessManagedMaterial(RigDef::ManagedMaterial & def)
Expand Down Expand Up @@ -2324,12 +2325,17 @@ void ActorSpawner::ProcessManagedMaterial(RigDef::ManagedMaterial & def)
def.specular_map = "";
}

// Create temporary placeholder
// Create fallback placeholders
// This is necessary to load meshes with original material names (= unchanged managed mat names)
// - if not found, OGRE substitutes them with 'BaseWhite' which breaks subsequent processing.
if (Ogre::MaterialManager::getSingleton().getByName(def.name, resource_group).isNull())
{
m_placeholder_managedmat->clone(def.name, /*changeGroup=*/true, resource_group);
LOG(fmt::format("[RoR] DBG ActorSpawner::ProcessManagedMaterial(): Creating placeholder for material '{}' in group '{}'", def.name, resource_group));
m_managedmat_placeholder_template->clone(def.name, /*changeGroup=*/true, resource_group);
}
else
{
LOG(fmt::format("[RoR] DBG ActorSpawner::ProcessManagedMaterial(): Placeholder already exists: '{}' in group '{}'", def.name, resource_group));
}

std::string custom_name = def.name + ACTOR_ID_TOKEN + TOSTRING(m_actor->ar_instance_id);
Expand Down
2 changes: 1 addition & 1 deletion source/main/physics/ActorSpawner.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ class ActorSpawner
RoR::FlexFactory m_flex_factory;
std::map<std::string, CustomMaterial> m_material_substitutions; //!< Maps original material names (shared) to their actor-specific substitutes; There's 1 substitute per 1 material, regardless of user count.
std::map<std::string, Ogre::MaterialPtr> m_managed_materials;
Ogre::MaterialPtr m_placeholder_managedmat;
Ogre::MaterialPtr m_managedmat_placeholder_template; //!< An 'error marker' material (bright magenta) to generate managedmaterial placeholders from.
Ogre::SceneNode* m_particles_parent_scenenode;
Ogre::MaterialPtr m_cab_trans_material;
Ogre::MaterialPtr m_simple_material_base;
Expand Down
16 changes: 15 additions & 1 deletion source/main/resources/CacheSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,20 @@ bool CacheSystem::CheckResourceLoaded(Ogre::String & filename, Ogre::String& gro
return false;
}

std::string CacheSystem::ComposeResourceGroupName(const CacheEntryPtr& entry)
{
// Compose group name as "{bundle <local path>}",
// where 'local path' means under 'Documenst\My Games\Rigs of Rods'.
// -----------------------------------------------------------------
std::string name = entry->resource_bundle_path; // Start from full path
size_t prefix_pos = name.find_first_not_of(App::sys_user_dir->getStr());
if (prefix_pos != std::string::npos)
{
name = name.substr(App::sys_user_dir->getStr().length());
}
return fmt::format("{{bundle {}}}", name);
}

void CacheSystem::LoadResource(CacheEntryPtr& entry)
{
if (!entry)
Expand All @@ -1220,7 +1234,7 @@ void CacheSystem::LoadResource(CacheEntryPtr& entry)
return;
}

Ogre::String group = "bundle " + entry->resource_bundle_path; // Compose group name from full path.
Ogre::String group = CacheSystem::ComposeResourceGroupName(entry);
bool readonly = entry->resource_bundle_type == "Zip"; // Make "FileSystem" (directory) bundles writable. Default is read-only.
bool recursive = false;

Expand Down
1 change: 1 addition & 0 deletions source/main/resources/CacheSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class CacheSystem

static Ogre::String StripUIDfromString(Ogre::String uidstr);
static Ogre::String StripSHA1fromString(Ogre::String sha1str);
static std::string ComposeResourceGroupName(const CacheEntryPtr& entry);

void ParseZipArchives(Ogre::String group);
bool ParseKnownFiles(Ogre::String group); // returns true if no known files are found
Expand Down

0 comments on commit 4315f1b

Please sign in to comment.