mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 16:29:55 +00:00
Creanup Distant Terrain code
- Cull terrain in the stock osg::CullVisitor - Do not compile composite maps for shadow camera - Do not abuse userdata for composite maps
This commit is contained in:
parent
e4ba6ecf15
commit
a730365ea1
8 changed files with 39 additions and 63 deletions
|
@ -30,7 +30,6 @@ ChunkManager::ChunkManager(Storage *storage, Resource::SceneManager *sceneMgr, T
|
|||
, mCompositeMapSize(512)
|
||||
, mCompositeMapLevel(1.f)
|
||||
, mMaxCompGeometrySize(1.f)
|
||||
, mCullingActive(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -208,7 +207,8 @@ osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Ve
|
|||
|
||||
mCompositeMapRenderer->addCompositeMap(compositeMap.get(), false);
|
||||
|
||||
transform->getOrCreateUserDataContainer()->setUserData(compositeMap);
|
||||
geometry->setCompositeMap(compositeMap);
|
||||
geometry->setCompositeMapRenderer(mCompositeMapRenderer);
|
||||
|
||||
TextureLayer layer;
|
||||
layer.mDiffuseMap = compositeMap->mTexture;
|
||||
|
@ -222,14 +222,7 @@ osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Ve
|
|||
}
|
||||
|
||||
transform->addChild(geometry);
|
||||
|
||||
if (!mCullingActive)
|
||||
{
|
||||
transform->setCullingActive(false);
|
||||
geometry->setCullingActive(false);
|
||||
}
|
||||
else
|
||||
transform->getBound();
|
||||
transform->getBound();
|
||||
|
||||
if (mSceneManager->getIncrementalCompileOperation())
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallba
|
|||
bool stopTraversal = (lodCallback->isSufficientDetail(this, dist)) || !getNumChildren();
|
||||
|
||||
if (stopTraversal)
|
||||
vd->add(this, true);
|
||||
vd->add(this);
|
||||
else
|
||||
{
|
||||
for (unsigned int i=0; i<getNumChildren(); ++i)
|
||||
|
@ -142,7 +142,7 @@ void QuadTreeNode::traverseTo(ViewData* vd, float size, const osg::Vec2f& center
|
|||
bool stopTraversal = (getSize() == size);
|
||||
|
||||
if (stopTraversal)
|
||||
vd->add(this, true);
|
||||
vd->add(this);
|
||||
else
|
||||
{
|
||||
for (unsigned int i=0; i<getNumChildren(); ++i)
|
||||
|
@ -159,7 +159,7 @@ void QuadTreeNode::intersect(ViewData* vd, TerrainLineIntersector* intersector)
|
|||
return;
|
||||
|
||||
if (getNumChildren() == 0)
|
||||
vd->add(this, true);
|
||||
vd->add(this);
|
||||
else
|
||||
{
|
||||
for (unsigned int i=0; i<getNumChildren(); ++i)
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
if (node->getSize() <= mMinSize)
|
||||
{
|
||||
// We arrived at a leaf.
|
||||
// Since the tree is used for LOD level selection instead of culling, we do not need to load an actual height data here.
|
||||
// Since the tree is used for LOD level selection instead of culling, we do not need to load the actual height data here.
|
||||
float minZ = -std::numeric_limits<float>::max();
|
||||
float maxZ = std::numeric_limits<float>::max();
|
||||
float cellWorldSize = mStorage->getCellWorldSize();
|
||||
|
@ -226,9 +226,6 @@ QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resour
|
|||
, mVertexLodMod(vertexLodMod)
|
||||
, mViewDistance(std::numeric_limits<float>::max())
|
||||
{
|
||||
// No need for culling on the Drawable / Transform level as the quad tree performs the culling already.
|
||||
mChunkManager->setCullingActive(false);
|
||||
|
||||
mChunkManager->setCompositeMapSize(compMapResolution);
|
||||
mChunkManager->setCompositeMapLevel(compMapLevel);
|
||||
mChunkManager->setMaxCompositeGeometrySize(maxCompGeometrySize);
|
||||
|
@ -362,44 +359,25 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
|
|||
else
|
||||
{
|
||||
osgUtil::IntersectionVisitor* iv = static_cast<osgUtil::IntersectionVisitor*>(&nv);
|
||||
osgUtil::LineSegmentIntersector* lineIntsersector = dynamic_cast<osgUtil::LineSegmentIntersector*>(iv->getIntersector());
|
||||
if (!lineIntsersector)
|
||||
throw std::runtime_error("Can not update QuadTreeWorld - the LineSegmentIntersector expected");
|
||||
osgUtil::LineSegmentIntersector* lineIntersector = dynamic_cast<osgUtil::LineSegmentIntersector*>(iv->getIntersector());
|
||||
if (!lineIntersector)
|
||||
throw std::runtime_error("Cannot update QuadTreeWorld: node visitor is not LineSegmentIntersector");
|
||||
|
||||
osg::Matrix matrix = osg::Matrix::identity();
|
||||
if (lineIntsersector->getCoordinateFrame() == osgUtil::Intersector::CoordinateFrame::MODEL && iv->getModelMatrix() == 0)
|
||||
matrix = lineIntsersector->getTransformation(*iv, osgUtil::Intersector::CoordinateFrame::MODEL);
|
||||
osg::ref_ptr<TerrainLineIntersector> terrainIntersector (new TerrainLineIntersector(lineIntsersector, matrix));
|
||||
if (lineIntersector->getCoordinateFrame() == osgUtil::Intersector::CoordinateFrame::MODEL && iv->getModelMatrix() == 0)
|
||||
matrix = lineIntersector->getTransformation(*iv, osgUtil::Intersector::CoordinateFrame::MODEL);
|
||||
osg::ref_ptr<TerrainLineIntersector> terrainIntersector (new TerrainLineIntersector(lineIntersector, matrix));
|
||||
mRootNode->intersect(vd, terrainIntersector);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCullVisitor)
|
||||
{
|
||||
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
|
||||
{
|
||||
ViewData::Entry& entry = vd->getEntry(i);
|
||||
entry.set(entry.mNode, !static_cast<osgUtil::CullVisitor*>(&nv)->isCulled(entry.mNode->getBoundingBox()));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
|
||||
{
|
||||
ViewData::Entry& entry = vd->getEntry(i);
|
||||
|
||||
loadRenderingNode(entry, vd, mVertexLodMod, mChunkManager.get());
|
||||
|
||||
if (entry.mVisible)
|
||||
{
|
||||
osg::UserDataContainer* udc = entry.mRenderingNode->getUserDataContainer();
|
||||
if (udc && udc->getUserData())
|
||||
{
|
||||
mCompositeMapRenderer->setImmediate(static_cast<CompositeMap*>(udc->getUserData()));
|
||||
udc->setUserData(nullptr);
|
||||
|
||||
}
|
||||
entry.mRenderingNode->accept(nv);
|
||||
}
|
||||
entry.mRenderingNode->accept(nv);
|
||||
}
|
||||
|
||||
if (!isCullVisitor)
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
|
||||
#include <components/sceneutil/lightmanager.hpp>
|
||||
|
||||
#include "compositemaprenderer.hpp"
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
|
||||
TerrainDrawable::TerrainDrawable()
|
||||
{
|
||||
}
|
||||
|
||||
TerrainDrawable::TerrainDrawable(const TerrainDrawable ©, const osg::CopyOp ©op)
|
||||
: osg::Geometry(copy, copyop)
|
||||
, mPasses(copy.mPasses)
|
||||
|
@ -63,6 +61,12 @@ void TerrainDrawable::cull(osgUtil::CullVisitor *cv)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mCompositeMap)
|
||||
{
|
||||
mCompositeMapRenderer->setImmediate(mCompositeMap);
|
||||
mCompositeMap = nullptr;
|
||||
}
|
||||
|
||||
bool pushedLight = mLightListCallback && mLightListCallback->pushLightState(this, cv);
|
||||
|
||||
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
||||
|
|
|
@ -16,6 +16,9 @@ namespace SceneUtil
|
|||
namespace Terrain
|
||||
{
|
||||
|
||||
class CompositeMap;
|
||||
class CompositeMapRenderer;
|
||||
|
||||
/**
|
||||
* Subclass of Geometry that supports built in multi-pass rendering and built in LightListCallback.
|
||||
*/
|
||||
|
@ -28,7 +31,8 @@ namespace Terrain
|
|||
virtual const char* className() const { return "TerrainDrawable"; }
|
||||
virtual const char* libraryName() const { return "Terrain"; }
|
||||
|
||||
TerrainDrawable();
|
||||
TerrainDrawable() = default;
|
||||
~TerrainDrawable() = default;
|
||||
TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop);
|
||||
|
||||
virtual void accept(osg::NodeVisitor &nv);
|
||||
|
@ -41,10 +45,15 @@ namespace Terrain
|
|||
|
||||
virtual void compileGLObjects(osg::RenderInfo& renderInfo) const;
|
||||
|
||||
void setCompositeMap(CompositeMap* map) { mCompositeMap = map; }
|
||||
void setCompositeMapRenderer(CompositeMapRenderer* renderer) { mCompositeMapRenderer = renderer; }
|
||||
|
||||
private:
|
||||
PassVector mPasses;
|
||||
|
||||
osg::ref_ptr<SceneUtil::LightListCallback> mLightListCallback;
|
||||
osg::ref_ptr<CompositeMap> mCompositeMap;
|
||||
osg::ref_ptr<CompositeMapRenderer> mCompositeMapRenderer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -61,11 +61,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
return nullptr;
|
||||
if (parent)
|
||||
parent->addChild(node);
|
||||
|
||||
osg::UserDataContainer* udc = node->getUserDataContainer();
|
||||
if (udc && udc->getUserData())
|
||||
mCompositeMapRenderer->setImmediate(static_cast<CompositeMap*>(udc->getUserData()));
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ void ViewData::copyFrom(const ViewData& other)
|
|||
mViewPoint = other.mViewPoint;
|
||||
}
|
||||
|
||||
void ViewData::add(QuadTreeNode *node, bool visible)
|
||||
void ViewData::add(QuadTreeNode *node)
|
||||
{
|
||||
unsigned int index = mNumEntries++;
|
||||
|
||||
|
@ -34,7 +34,7 @@ void ViewData::add(QuadTreeNode *node, bool visible)
|
|||
mEntries.resize(index+1);
|
||||
|
||||
Entry& entry = mEntries[index];
|
||||
if (entry.set(node, visible))
|
||||
if (entry.set(node))
|
||||
mChanged = true;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ void ViewData::reset()
|
|||
{
|
||||
// clear any unused entries
|
||||
for (unsigned int i=mNumEntries; i<mEntries.size(); ++i)
|
||||
mEntries[i].set(nullptr, false);
|
||||
mEntries[i].set(nullptr);
|
||||
|
||||
// reset index for next frame
|
||||
mNumEntries = 0;
|
||||
|
@ -83,7 +83,7 @@ void ViewData::reset()
|
|||
void ViewData::clear()
|
||||
{
|
||||
for (unsigned int i=0; i<mEntries.size(); ++i)
|
||||
mEntries[i].set(nullptr, false);
|
||||
mEntries[i].set(nullptr);
|
||||
mNumEntries = 0;
|
||||
mLastUsageTimeStamp = 0;
|
||||
mChanged = false;
|
||||
|
@ -100,15 +100,13 @@ bool ViewData::contains(QuadTreeNode *node)
|
|||
|
||||
ViewData::Entry::Entry()
|
||||
: mNode(nullptr)
|
||||
, mVisible(true)
|
||||
, mLodFlags(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ViewData::Entry::set(QuadTreeNode *node, bool visible)
|
||||
bool ViewData::Entry::set(QuadTreeNode *node)
|
||||
{
|
||||
mVisible = visible;
|
||||
if (node == mNode)
|
||||
return false;
|
||||
else
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Terrain
|
|||
ViewData();
|
||||
~ViewData();
|
||||
|
||||
void add(QuadTreeNode* node, bool visible);
|
||||
void add(QuadTreeNode* node);
|
||||
|
||||
void reset();
|
||||
|
||||
|
@ -33,10 +33,9 @@ namespace Terrain
|
|||
{
|
||||
Entry();
|
||||
|
||||
bool set(QuadTreeNode* node, bool visible);
|
||||
bool set(QuadTreeNode* node);
|
||||
|
||||
QuadTreeNode* mNode;
|
||||
bool mVisible;
|
||||
|
||||
unsigned int mLodFlags;
|
||||
osg::ref_ptr<osg::Node> mRenderingNode;
|
||||
|
|
Loading…
Reference in a new issue