1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-19 12:39:42 +00:00

Do not store a LOD callback in the every QuadTreeNode

This commit is contained in:
bzzt 2019-02-20 13:37:00 +00:00 committed by Andrei Kortunov
parent a61c0aaee1
commit e4ba6ecf15
4 changed files with 13 additions and 30 deletions

View file

@ -108,7 +108,7 @@ void QuadTreeNode::initNeighbours()
getChild(i)->initNeighbours(); getChild(i)->initNeighbours();
} }
void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, float maxDist) void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist)
{ {
if (!hasValidBounds()) if (!hasValidBounds())
return; return;
@ -117,14 +117,14 @@ void QuadTreeNode::traverse(ViewData* vd, const osg::Vec3f& viewPoint, float max
if (dist > maxDist) if (dist > maxDist)
return; return;
bool stopTraversal = (mLodCallback->isSufficientDetail(this, dist)) || !getNumChildren(); bool stopTraversal = (lodCallback->isSufficientDetail(this, dist)) || !getNumChildren();
if (stopTraversal) if (stopTraversal)
vd->add(this, true); vd->add(this, true);
else else
{ {
for (unsigned int i=0; i<getNumChildren(); ++i) for (unsigned int i=0; i<getNumChildren(); ++i)
getChild(i)->traverse(vd, viewPoint, maxDist); getChild(i)->traverse(vd, viewPoint, lodCallback, maxDist);
} }
} }
@ -167,16 +167,6 @@ void QuadTreeNode::intersect(ViewData* vd, TerrainLineIntersector* intersector)
} }
} }
void QuadTreeNode::setLodCallback(LodCallback *lodCallback)
{
mLodCallback = lodCallback;
}
LodCallback *QuadTreeNode::getLodCallback()
{
return mLodCallback;
}
void QuadTreeNode::setBoundingBox(const osg::BoundingBox &boundingBox) void QuadTreeNode::setBoundingBox(const osg::BoundingBox &boundingBox)
{ {
mBoundingBox = boundingBox; mBoundingBox = boundingBox;

View file

@ -91,9 +91,8 @@ namespace Terrain
/// center in cell coordinates /// center in cell coordinates
const osg::Vec2f& getCenter() const; const osg::Vec2f& getCenter() const;
/// Optimized version of traverse() that doesn't incur the overhead of NodeVisitor double-dispatch or fetching the various variables. /// Traverse nodes according to LOD selection.
/// Note this doesn't do any culling. void traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist);
void traverse(ViewData* vd, const osg::Vec3f& viewPoint, float maxDist);
/// Traverse to a specific node and add only that node. /// Traverse to a specific node and add only that node.
void traverseTo(ViewData* vd, float size, const osg::Vec2f& center); void traverseTo(ViewData* vd, float size, const osg::Vec2f& center);
@ -101,11 +100,6 @@ namespace Terrain
/// Adds all leaf nodes which intersect the line from start to end /// Adds all leaf nodes which intersect the line from start to end
void intersect(ViewData* vd, TerrainLineIntersector* intersector); void intersect(ViewData* vd, TerrainLineIntersector* intersector);
/// Set the Lod callback to use for determining when to stop traversing further down the quad tree.
void setLodCallback(LodCallback* lodCallback);
LodCallback* getLodCallback();
private: private:
QuadTreeNode* mParent; QuadTreeNode* mParent;
@ -117,8 +111,6 @@ namespace Terrain
bool mValidBounds; bool mValidBounds;
float mSize; float mSize;
osg::Vec2f mCenter; osg::Vec2f mCenter;
osg::ref_ptr<LodCallback> mLodCallback;
}; };
} }

View file

@ -97,9 +97,8 @@ private:
class QuadTreeBuilder class QuadTreeBuilder
{ {
public: public:
QuadTreeBuilder(Terrain::Storage* storage, float lodFactor, float minSize) QuadTreeBuilder(Terrain::Storage* storage, float minSize)
: mStorage(storage) : mStorage(storage)
, mLodFactor(lodFactor)
, mMinX(0.f), mMaxX(0.f), mMinY(0.f), mMaxY(0.f) , mMinX(0.f), mMaxX(0.f), mMinY(0.f), mMaxY(0.f)
, mMinSize(minSize) , mMinSize(minSize)
{ {
@ -119,7 +118,6 @@ public:
float centerY = (mMinY+mMaxY)/2.f + (size-origSizeY)/2.f; float centerY = (mMinY+mMaxY)/2.f + (size-origSizeY)/2.f;
mRootNode = new RootNode(size, osg::Vec2f(centerX, centerY)); mRootNode = new RootNode(size, osg::Vec2f(centerX, centerY));
mRootNode->setLodCallback(new DefaultLodCallback(mLodFactor, mMinSize));
addChildren(mRootNode); addChildren(mRootNode);
mRootNode->initNeighbours(); mRootNode->initNeighbours();
@ -168,7 +166,6 @@ public:
} }
osg::ref_ptr<QuadTreeNode> node = new QuadTreeNode(parent, direction, size, center); osg::ref_ptr<QuadTreeNode> node = new QuadTreeNode(parent, direction, size, center);
node->setLodCallback(parent->getLodCallback());
if (center.x() - halfSize > mMaxX if (center.x() - halfSize > mMaxX
|| center.x() + halfSize < mMinX || center.x() + halfSize < mMinX
@ -218,6 +215,7 @@ private:
float mMinSize; float mMinSize;
osg::ref_ptr<RootNode> mRootNode; osg::ref_ptr<RootNode> mRootNode;
osg::ref_ptr<LodCallback> mLodCallback;
}; };
QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask, int borderMask, int compMapResolution, float compMapLevel, float lodFactor, int vertexLodMod, float maxCompGeometrySize) QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask, int borderMask, int compMapResolution, float compMapLevel, float lodFactor, int vertexLodMod, float maxCompGeometrySize)
@ -359,7 +357,7 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5,y+0.5)); mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5,y+0.5));
} }
else else
mRootNode->traverse(vd, cv->getViewPoint(), mViewDistance); mRootNode->traverse(vd, cv->getViewPoint(), mLodCallback, mViewDistance);
} }
else else
{ {
@ -424,7 +422,8 @@ void QuadTreeWorld::ensureQuadTreeBuilt()
return; return;
const float minSize = 1/8.f; const float minSize = 1/8.f;
QuadTreeBuilder builder(mStorage, mLodFactor, minSize); mLodCallback = new DefaultLodCallback(mLodFactor, minSize);
QuadTreeBuilder builder(mStorage, minSize);
builder.build(); builder.build();
mRootNode = builder.getRootNode(); mRootNode = builder.getRootNode();
@ -470,7 +469,7 @@ void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, std::atomic
ViewData* vd = static_cast<ViewData*>(view); ViewData* vd = static_cast<ViewData*>(view);
vd->setViewPoint(viewPoint); vd->setViewPoint(viewPoint);
mRootNode->traverse(vd, viewPoint, mViewDistance); mRootNode->traverse(vd, viewPoint, mLodCallback, mViewDistance);
for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i) for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i)
{ {

View file

@ -15,6 +15,7 @@ namespace Terrain
{ {
class RootNode; class RootNode;
class ViewDataMap; class ViewDataMap;
class LodCallback;
/// @brief Terrain implementation that loads cells into a Quad Tree, with geometry LOD and texture LOD. /// @brief Terrain implementation that loads cells into a Quad Tree, with geometry LOD and texture LOD.
class QuadTreeWorld : public TerrainGrid // note: derived from TerrainGrid is only to render default cells (see loadCell) class QuadTreeWorld : public TerrainGrid // note: derived from TerrainGrid is only to render default cells (see loadCell)
@ -48,6 +49,7 @@ namespace Terrain
osg::ref_ptr<RootNode> mRootNode; osg::ref_ptr<RootNode> mRootNode;
osg::ref_ptr<ViewDataMap> mViewDataMap; osg::ref_ptr<ViewDataMap> mViewDataMap;
osg::ref_ptr<LodCallback> mLodCallback;
OpenThreads::Mutex mQuadTreeMutex; OpenThreads::Mutex mQuadTreeMutex;
bool mQuadTreeBuilt; bool mQuadTreeBuilt;