From 9b048003b9e40cf14b5d310ee615fb7b44b24604 Mon Sep 17 00:00:00 2001 From: Edgar Date: Thu, 9 Jan 2025 14:39:46 +0100 Subject: [PATCH] :bug: Fixed LODs not being loaded The code for loading LODs got removed at some point --- source/main/Application.cpp | 1 + source/main/Application.h | 1 + source/main/gui/panels/GUI_GameSettings.cpp | 2 + source/main/resources/ContentManager.cpp | 3 + source/main/system/CVar.cpp | 1 + source/main/utils/MeshObject.cpp | 122 +++++++++++++------- 6 files changed, 91 insertions(+), 39 deletions(-) diff --git a/source/main/Application.cpp b/source/main/Application.cpp index b5929b6d22..80c46fc97d 100644 --- a/source/main/Application.cpp +++ b/source/main/Application.cpp @@ -248,6 +248,7 @@ CVar* gfx_flexbody_cache; CVar* gfx_reduce_shadows; CVar* gfx_enable_rtshaders; CVar* gfx_alt_actor_materials; +CVar* gfx_auto_lod; // Flexbodies CVar* flexbody_defrag_enabled; diff --git a/source/main/Application.h b/source/main/Application.h index f127b7da1a..840709c5d3 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -519,6 +519,7 @@ extern CVar* gfx_flexbody_cache; extern CVar* gfx_reduce_shadows; extern CVar* gfx_enable_rtshaders; extern CVar* gfx_alt_actor_materials; +extern CVar* gfx_auto_lod; // Flexbodies extern CVar* flexbody_defrag_enabled; diff --git a/source/main/gui/panels/GUI_GameSettings.cpp b/source/main/gui/panels/GUI_GameSettings.cpp index 1612e1c03d..d449923723 100644 --- a/source/main/gui/panels/GUI_GameSettings.cpp +++ b/source/main/gui/panels/GUI_GameSettings.cpp @@ -410,6 +410,8 @@ void GameSettings::DrawGraphicsSettings() DrawGIntCheck(App::gfx_particles_mode, _LC("GameSettings", "Enable particle gfx")); DrawGIntCheck(App::gfx_skidmarks_mode, _LC("GameSettings", "Enable skidmarks")); + DrawGCheckbox(App::gfx_auto_lod, _LC("GameSettings", "Enable OGRE's automatic mesh LOD generator (Increases loading times)")); + DrawGCheckbox(App::gfx_envmap_enabled, _LC("GameSettings", "Realtime reflections")); if (App::gfx_envmap_enabled->getBool()) { diff --git a/source/main/resources/ContentManager.cpp b/source/main/resources/ContentManager.cpp index b47bc259e1..4fcf5600b2 100644 --- a/source/main/resources/ContentManager.cpp +++ b/source/main/resources/ContentManager.cpp @@ -56,6 +56,7 @@ #include #include #include +#include using namespace Ogre; using namespace RoR; @@ -243,6 +244,8 @@ void ContentManager::InitContentManager() #ifdef USE_OPENAL App::GetSoundScriptManager()->setLoadingBaseSounds(false); #endif // USE_OPENAL + + new Ogre::MeshLodGenerator(); } void ContentManager::InitModCache(CacheValidity validity) diff --git a/source/main/system/CVar.cpp b/source/main/system/CVar.cpp index 85bf45dd6b..a2c5b706b1 100644 --- a/source/main/system/CVar.cpp +++ b/source/main/system/CVar.cpp @@ -190,6 +190,7 @@ void Console::cVarSetupBuiltins() App::gfx_reduce_shadows = this->cVarCreate("gfx_reduce_shadows", "Shadow optimizations", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "true"); App::gfx_enable_rtshaders = this->cVarCreate("gfx_enable_rtshaders", "Use RTShader System", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "false"); App::gfx_alt_actor_materials = this->cVarCreate("gfx_alt_actor_materials", "Use alternate vehicle materials", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "false"); + App::gfx_auto_lod = this->cVarCreate("gfx_auto_lod", "Use OGREs Automatic Mesh LOD Generator", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "true"); App::flexbody_defrag_enabled = this->cVarCreate("flexbody_defrag_enabled", "", CVAR_TYPE_BOOL); App::flexbody_defrag_const_penalty = this->cVarCreate("flexbody_defrag_const_penalty", "", CVAR_TYPE_INT, "7"); diff --git a/source/main/utils/MeshObject.cpp b/source/main/utils/MeshObject.cpp index 1a6183f326..0e8d07b2b6 100644 --- a/source/main/utils/MeshObject.cpp +++ b/source/main/utils/MeshObject.cpp @@ -27,15 +27,16 @@ #include "Actor.h" #include "Application.h" #include "GfxScene.h" -#include "MeshLodGenerator/OgreMeshLodGenerator.h" +#include "Terrain.h" + +#include +#include using namespace Ogre; using namespace RoR; -MeshObject::MeshObject(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName, Ogre::SceneNode* m_scene_node) - : m_scene_node(m_scene_node) - , m_entity(nullptr) - , m_cast_shadows(true) +MeshObject::MeshObject(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName, Ogre::SceneNode *m_scene_node) + : m_scene_node(m_scene_node), m_entity(nullptr), m_cast_shadows(true) { this->createEntity(meshName, entityRG, entityName); } @@ -73,53 +74,96 @@ void MeshObject::createEntity(Ogre::String meshName, Ogre::String entityRG, Ogre try { - m_mesh = Ogre::MeshManager::getSingleton().load(meshName, entityRG); - - // important: you need to add the LODs before creating the entity - // now find possible LODs, needs to be done before calling createEntity() - String basename, ext; - StringUtil::splitBaseFilename(meshName, basename, ext); - - // the classic LODs - FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_lod*.mesh"); - for (FileInfoList::iterator iterFiles = files->begin(); iterFiles != files->end(); ++iterFiles) - { - String format = basename + "_lod%d.mesh"; - int i = -1; - int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i); + m_mesh = Ogre::MeshManager::getSingleton().getByName(meshName, entityRG); - if (r <= 0 || i < 0) - continue; - - Ogre::MeshManager::getSingleton().load(iterFiles->filename, entityRG); - } - - // the custom LODs - FileInfoListPtr files2 = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_clod_*.mesh"); - for (FileInfoList::iterator iterFiles = files2->begin(); iterFiles != files2->end(); ++iterFiles) + // Mesh hasn't been loaded yet + if (m_mesh == nullptr) { - // and custom LODs - String format = basename + "_clod_%d.mesh"; - int i = -1; - int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i); - if (r <= 0 || i < 0) - continue; - - Ogre::MeshManager::getSingleton().load(iterFiles->filename, entityRG); + m_mesh = Ogre::MeshManager::getSingleton().load(meshName, entityRG); + + // important: you need to add the LODs before creating the entity + // now find possible LODs, needs to be done before calling createEntity() + String basename, ext; + StringUtil::splitBaseFilename(meshName, basename, ext); + + bool lod_available = false; + Ogre::LodConfig config(m_mesh); + + // the classic LODs + FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_lod*.mesh"); + for (FileInfoList::iterator iterFiles = files->begin(); iterFiles != files->end(); ++iterFiles) + { + String format = basename + "_lod%d.mesh"; + int i = -1; + int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i); + + if (r <= 0 || i < 0) + continue; + + float distance = 3; + + // we need to tune this according to our sightrange + if (App::gfx_sight_range->getInt() > Terrain::UNLIMITED_SIGHTRANGE) + { + // unlimited + if (i == 1) + distance = 200; + else if (i == 2) + distance = 600; + else if (i == 3) + distance = 2000; + else if (i == 4) + distance = 5000; + } + else + { + // limited + int sightrange = App::gfx_sight_range->getInt(); + if (i == 1) + distance = std::max(20.0f, sightrange * 0.1f); + else if (i == 2) + distance = std::max(20.0f, sightrange * 0.2f); + else if (i == 3) + distance = std::max(20.0f, sightrange * 0.3f); + else if (i == 4) + distance = std::max(20.0f, sightrange * 0.4f); + } + config.createManualLodLevel(distance, iterFiles->filename); + lod_available = true; + } + + // the custom LODs + FileInfoListPtr files2 = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_clod_*.mesh"); + for (FileInfoList::iterator iterFiles = files2->begin(); iterFiles != files2->end(); ++iterFiles) + { + // and custom LODs + String format = basename + "_clod_%d.mesh"; + int i = -1; + int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i); + if (r <= 0 || i < 0) + continue; + + config.createManualLodLevel(i, iterFiles->filename); + lod_available = true; + } + + if (lod_available) + Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config); + else if (App::gfx_auto_lod->getBool()) + Ogre::MeshLodGenerator::getSingleton().generateAutoconfiguredLodLevels(m_mesh); } // now create an entity around the mesh and attach it to the scene graph - m_entity = App::GetGfxScene()->GetSceneManager()->createEntity(entityName, meshName, entityRG); m_entity->setCastShadows(m_cast_shadows); m_scene_node->attachObject(m_entity); m_scene_node->setVisible(true); } - catch (Ogre::Exception& e) + catch (Ogre::Exception &e) { RoR::LogFormat("[RoR] Error creating entity of mesh '%s' (group: '%s'), message: %s", - meshName.c_str(), entityRG.c_str(), e.getFullDescription().c_str()); + meshName.c_str(), entityRG.c_str(), e.getFullDescription().c_str()); return; } }