Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Fixed LODs not being loaded #3207

Merged
merged 1 commit into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/main/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions source/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions source/main/gui/panels/GUI_GameSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to refer to it as "OGRE's automatic mesh LOD generator"? Could it just be "Enable automatic mesh LOD generator"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^


DrawGCheckbox(App::gfx_envmap_enabled, _LC("GameSettings", "Realtime reflections"));
if (App::gfx_envmap_enabled->getBool())
{
Expand Down
3 changes: 3 additions & 0 deletions source/main/resources/ContentManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <sstream>
#include <OgreMeshLodGenerator.h>

using namespace Ogre;
using namespace RoR;
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions source/main/system/CVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
122 changes: 83 additions & 39 deletions source/main/utils/MeshObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@
#include "Actor.h"
#include "Application.h"
#include "GfxScene.h"
#include "MeshLodGenerator/OgreMeshLodGenerator.h"
#include "Terrain.h"

#include <OgreMeshLodGenerator.h>
#include <OgreLodConfig.h>

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);
}
Expand Down Expand Up @@ -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;
}
}
Loading