1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-31 19:20:26 +00:00

ground cover manager and object paging exists per worldspace.

They don't work though. But at least it doesn't crash. You get a morrowind world on top of the skyrim world.
But it fixes the crashes.
This commit is contained in:
florent.teppe 2023-05-23 00:23:47 +02:00
parent 22dc383f63
commit b29be74491
2 changed files with 52 additions and 38 deletions

View File

@ -321,6 +321,7 @@ namespace MWRender
, mFieldOfViewOverride(0.f) , mFieldOfViewOverride(0.f)
, mFieldOfView(Settings::camera().mFieldOfView) , mFieldOfView(Settings::camera().mFieldOfView)
, mFirstPersonFieldOfView(Settings::camera().mFirstPersonFieldOfView) , mFirstPersonFieldOfView(Settings::camera().mFirstPersonFieldOfView)
, mGroundCoverStore(groundcoverStore)
{ {
bool reverseZ = SceneUtil::AutoDepth::isReversed(); bool reverseZ = SceneUtil::AutoDepth::isReversed();
auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString( auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(
@ -458,19 +459,10 @@ namespace MWRender
mTerrainStorage = std::make_unique<TerrainStorage>(mResourceSystem, normalMapPattern, heightMapPattern, mTerrainStorage = std::make_unique<TerrainStorage>(mResourceSystem, normalMapPattern, heightMapPattern,
useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps); useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps);
mTerrain = &getWorldspaceTerrain(ESM::Cell::sDefaultWorldspaceId); WorldspaceChunkMgr& chunkMgr = getWorldspaceChunkMgr(ESM::Cell::sDefaultWorldspaceId);
bool groundcover = Settings::Manager::getBool("enabled", "Groundcover"); mTerrain = chunkMgr.mTerrain.get();
mGroundcover = chunkMgr.mGroundcover.get();
if (groundcover) mObjectPaging = chunkMgr.mObjectPaging.get();
{
float density = Settings::Manager::getFloat("density", "Groundcover");
density = std::clamp(density, 0.f, 1.f);
mGroundcover = std::make_unique<Groundcover>(
mResourceSystem->getSceneManager(), density, groundcoverDistance, groundcoverStore);
static_cast<Terrain::QuadTreeWorld*>(mTerrain)->addChunkManager(mGroundcover.get());
mResourceSystem->addResourceManager(mGroundcover.get());
}
mStateUpdater = new StateUpdater; mStateUpdater = new StateUpdater;
sceneRoot->addUpdateCallback(mStateUpdater); sceneRoot->addUpdateCallback(mStateUpdater);
@ -757,8 +749,8 @@ namespace MWRender
if (store->getCell()->isExterior()) if (store->getCell()->isExterior())
{ {
getWorldspaceTerrain(store->getCell()->getWorldSpace()) getWorldspaceChunkMgr(store->getCell()->getWorldSpace())
.unloadCell(store->getCell()->getGridX(), store->getCell()->getGridY()); .mTerrain->unloadCell(store->getCell()->getGridX(), store->getCell()->getGridY());
} }
mWater->removeCell(store); mWater->removeCell(store);
@ -770,11 +762,13 @@ namespace MWRender
mWater->setCullCallback(nullptr); mWater->setCullCallback(nullptr);
else else
{ {
Terrain::World* newTerrain = &getWorldspaceTerrain(worldspace); WorldspaceChunkMgr& newChunks = getWorldspaceChunkMgr(worldspace);
if (newTerrain != mTerrain) if (newChunks.mTerrain.get() != mTerrain)
{ {
mTerrain->enable(false); mTerrain->enable(false);
mTerrain = newTerrain; mTerrain = newChunks.mTerrain.get();
mGroundcover = newChunks.mGroundcover.get();
mObjectPaging = newChunks.mObjectPaging.get();
} }
} }
mTerrain->enable(enable); mTerrain->enable(enable);
@ -1328,12 +1322,12 @@ namespace MWRender
mStateUpdater->setFogColor(color); mStateUpdater->setFogColor(color);
} }
Terrain::World& RenderingManager::getWorldspaceTerrain(ESM::RefId worldspace) RenderingManager::WorldspaceChunkMgr& RenderingManager::getWorldspaceChunkMgr(ESM::RefId worldspace)
{ {
auto existingTerrain = mWorldspaceTerrains.find(worldspace); auto existingChunkMgr = mWorldspaceChunks.find(worldspace);
if (existingTerrain != mWorldspaceTerrains.end()) if (existingChunkMgr != mWorldspaceChunks.end())
return *existingTerrain->second.get(); return existingChunkMgr->second;
std::unique_ptr<Terrain::World> newTerrain; RenderingManager::WorldspaceChunkMgr newChunkMgr;
const float lodFactor = Settings::Manager::getFloat("lod factor", "Terrain"); const float lodFactor = Settings::Manager::getFloat("lod factor", "Terrain");
bool groundcover = Settings::Manager::getBool("enabled", "Groundcover"); bool groundcover = Settings::Manager::getBool("enabled", "Groundcover");
@ -1348,27 +1342,38 @@ namespace MWRender
float maxCompGeometrySize = Settings::Manager::getFloat("max composite geometry size", "Terrain"); float maxCompGeometrySize = Settings::Manager::getFloat("max composite geometry size", "Terrain");
maxCompGeometrySize = std::max(maxCompGeometrySize, 1.f); maxCompGeometrySize = std::max(maxCompGeometrySize, 1.f);
bool debugChunks = Settings::Manager::getBool("debug chunks", "Terrain"); bool debugChunks = Settings::Manager::getBool("debug chunks", "Terrain");
newTerrain = std::make_unique<Terrain::QuadTreeWorld>(mSceneRoot, mRootNode, mResourceSystem, auto quadTreeWorld = std::make_unique<Terrain::QuadTreeWorld>(mSceneRoot, mRootNode, mResourceSystem,
mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug, compMapResolution, compMapLevel, mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug, compMapResolution, compMapLevel,
lodFactor, vertexLodMod, maxCompGeometrySize, debugChunks, worldspace); lodFactor, vertexLodMod, maxCompGeometrySize, debugChunks, worldspace);
if (Settings::Manager::getBool("object paging", "Terrain")) if (Settings::Manager::getBool("object paging", "Terrain"))
{ {
mObjectPaging = std::make_unique<ObjectPaging>(mResourceSystem->getSceneManager()); newChunkMgr.mObjectPaging = std::make_unique<ObjectPaging>(mResourceSystem->getSceneManager());
static_cast<Terrain::QuadTreeWorld*>(newTerrain.get())->addChunkManager(mObjectPaging.get()); quadTreeWorld->addChunkManager(newChunkMgr.mObjectPaging.get());
mResourceSystem->addResourceManager(mObjectPaging.get()); mResourceSystem->addResourceManager(newChunkMgr.mObjectPaging.get());
} }
if (groundcover)
{
float groundcoverDistance
= std::max(0.f, Settings::Manager::getFloat("rendering distance", "Groundcover"));
float density = Settings::Manager::getFloat("density", "Groundcover");
density = std::clamp(density, 0.f, 1.f);
newChunkMgr.mGroundcover = std::make_unique<Groundcover>(
mResourceSystem->getSceneManager(), density, groundcoverDistance, mGroundCoverStore);
quadTreeWorld->addChunkManager(newChunkMgr.mGroundcover.get());
mResourceSystem->addResourceManager(newChunkMgr.mGroundcover.get());
}
newChunkMgr.mTerrain = std::move(quadTreeWorld);
} }
else else
newTerrain = std::make_unique<Terrain::TerrainGrid>(mSceneRoot, mRootNode, mResourceSystem, newChunkMgr.mTerrain = std::make_unique<Terrain::TerrainGrid>(mSceneRoot, mRootNode, mResourceSystem,
mTerrainStorage.get(), Mask_Terrain, worldspace, Mask_PreCompile, Mask_Debug); mTerrainStorage.get(), Mask_Terrain, worldspace, Mask_PreCompile, Mask_Debug);
newTerrain->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells")); newChunkMgr.mTerrain->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells"));
float distanceMult = std::cos(osg::DegreesToRadians(std::min(mFieldOfView, 140.f)) / 2.f); float distanceMult = std::cos(osg::DegreesToRadians(std::min(mFieldOfView, 140.f)) / 2.f);
newTerrain->setViewDistance(mViewDistance * (distanceMult ? 1.f / distanceMult : 1.f)); newChunkMgr.mTerrain->setViewDistance(mViewDistance * (distanceMult ? 1.f / distanceMult : 1.f));
Terrain::World* result = newTerrain.get(); return mWorldspaceChunks.emplace(worldspace, std::move(newChunkMgr)).first->second;
mWorldspaceTerrains.emplace(worldspace, std::move(newTerrain));
return *result;
} }
void RenderingManager::reportStats() const void RenderingManager::reportStats() const
@ -1474,7 +1479,7 @@ namespace MWRender
float RenderingManager::getTerrainHeightAt(const osg::Vec3f& pos, ESM::RefId worldspace) float RenderingManager::getTerrainHeightAt(const osg::Vec3f& pos, ESM::RefId worldspace)
{ {
return getWorldspaceTerrain(worldspace).getHeightAt(pos); return getWorldspaceChunkMgr(worldspace).mTerrain->getHeightAt(pos);
} }
void RenderingManager::overrideFieldOfView(float val) void RenderingManager::overrideFieldOfView(float val)

View File

@ -282,7 +282,15 @@ namespace MWRender
void updateAmbient(); void updateAmbient();
void setFogColor(const osg::Vec4f& color); void setFogColor(const osg::Vec4f& color);
void updateThirdPersonViewMode(); void updateThirdPersonViewMode();
Terrain::World& getWorldspaceTerrain(ESM::RefId worldspace);
struct WorldspaceChunkMgr
{
std::unique_ptr<Terrain::World> mTerrain;
std::unique_ptr<ObjectPaging> mObjectPaging;
std::unique_ptr<Groundcover> mGroundcover;
};
WorldspaceChunkMgr& getWorldspaceChunkMgr(ESM::RefId worldspace);
void reportStats() const; void reportStats() const;
@ -314,11 +322,11 @@ namespace MWRender
std::unique_ptr<Pathgrid> mPathgrid; std::unique_ptr<Pathgrid> mPathgrid;
std::unique_ptr<Objects> mObjects; std::unique_ptr<Objects> mObjects;
std::unique_ptr<Water> mWater; std::unique_ptr<Water> mWater;
std::unordered_map<ESM::RefId, std::unique_ptr<Terrain::World>> mWorldspaceTerrains; std::unordered_map<ESM::RefId, WorldspaceChunkMgr> mWorldspaceChunks;
Terrain::World* mTerrain; Terrain::World* mTerrain;
std::unique_ptr<TerrainStorage> mTerrainStorage; std::unique_ptr<TerrainStorage> mTerrainStorage;
std::unique_ptr<ObjectPaging> mObjectPaging; ObjectPaging* mObjectPaging;
std::unique_ptr<Groundcover> mGroundcover; Groundcover* mGroundcover;
std::unique_ptr<SkyManager> mSky; std::unique_ptr<SkyManager> mSky;
std::unique_ptr<FogManager> mFog; std::unique_ptr<FogManager> mFog;
std::unique_ptr<ScreenshotManager> mScreenshotManager; std::unique_ptr<ScreenshotManager> mScreenshotManager;
@ -346,6 +354,7 @@ namespace MWRender
float mFirstPersonFieldOfView; float mFirstPersonFieldOfView;
bool mUpdateProjectionMatrix = false; bool mUpdateProjectionMatrix = false;
bool mNight = false; bool mNight = false;
const MWWorld::GroundcoverStore& mGroundCoverStore;
void operator=(const RenderingManager&); void operator=(const RenderingManager&);
RenderingManager(const RenderingManager&); RenderingManager(const RenderingManager&);