Converted osg::LOD from used n+1 successive ranges to n min/max ranges,
one min/max pair per child. Converted the rest of the OSG to use the new osg::LOD node.
This commit is contained in:
@@ -132,6 +132,25 @@ void CullVisitor::reset()
|
||||
|
||||
}
|
||||
|
||||
float CullVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODBias) const
|
||||
{
|
||||
if (withLODBias) return (pos-getEyeLocal()).length()*getLODBias();
|
||||
else return (pos-getEyeLocal()).length();
|
||||
}
|
||||
|
||||
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
|
||||
{
|
||||
return -(coord[0]*matrix(0,2)+coord[1]*matrix(1,2)+coord[2]*matrix(2,2)+matrix(3,2));
|
||||
}
|
||||
|
||||
float CullVisitor::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODBias) const
|
||||
{
|
||||
const Matrix& matrix = *_modelviewStack.back();
|
||||
float dist = distance(pos,matrix);
|
||||
|
||||
if (withLODBias) return dist*getLODBias();
|
||||
else return dist*getLODBias();
|
||||
}
|
||||
|
||||
void CullVisitor::popProjectionMatrix()
|
||||
{
|
||||
@@ -168,10 +187,6 @@ void CullVisitor::popProjectionMatrix()
|
||||
CullStack::popProjectionMatrix();
|
||||
}
|
||||
|
||||
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
|
||||
{
|
||||
return -(coord[0]*matrix(0,2)+coord[1]*matrix(1,2)+coord[2]*matrix(2,2)+matrix(3,2));
|
||||
}
|
||||
|
||||
|
||||
void CullVisitor::updateCalculatedNearFar(const osg::Matrix& matrix,const osg::BoundingBox& bb)
|
||||
@@ -459,9 +474,6 @@ void CullVisitor::apply(LOD& node)
|
||||
{
|
||||
if (isCulled(node)) return;
|
||||
|
||||
int eval = node.evaluate(getEyeLocal(),_LODBias);
|
||||
if (eval<0) return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
@@ -469,8 +481,7 @@ void CullVisitor::apply(LOD& node)
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
//notify(INFO) << "selecting child "<<eval<< std::endl;
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@@ -538,9 +549,6 @@ void CullVisitor::apply(Impostor& node)
|
||||
|
||||
osg::Vec3 eyeLocal = getEyeLocal();
|
||||
|
||||
int eval = node.evaluate(eyeLocal,_LODBias);
|
||||
if (eval<0) return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
@@ -557,13 +565,13 @@ void CullVisitor::apply(Impostor& node)
|
||||
{
|
||||
// outwith the impostor distance threshold therefore simple
|
||||
// traverse the appropriate child of the LOD.
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
}
|
||||
else if (_viewportStack.empty())
|
||||
{
|
||||
// need to use impostor but no valid viewport is defined to simply
|
||||
// default to using the LOD child as above.
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -623,7 +631,7 @@ void CullVisitor::apply(Impostor& node)
|
||||
{
|
||||
// no impostor has been selected or created so default to
|
||||
// traversing the usual LOD selected child.
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -645,7 +653,6 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
const Matrix& matrix = getModelViewMatrix();
|
||||
const BoundingSphere& bs = node.getBound();
|
||||
osg::Vec3 eye_local = getEyeLocal();
|
||||
int eval = node.evaluate(eye_local,_LODBias);
|
||||
|
||||
if (!bs.valid())
|
||||
{
|
||||
@@ -777,7 +784,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
{
|
||||
|
||||
// traversing the usual LOD selected child.
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +96,7 @@ void InsertImpostorsVisitor::insertImpostors()
|
||||
|
||||
// standard LOD settings
|
||||
impostor->addChild(group);
|
||||
impostor->setRange(0,0.0f);
|
||||
impostor->setRange(1,1e7f);
|
||||
impostor->setCenter(bs.center());
|
||||
impostor->setRange(0,0.0f,1e7f);
|
||||
|
||||
// impostor specfic settings.
|
||||
impostor->setImpostorThresholdToBound(_impostorThresholdRatio);
|
||||
@@ -147,14 +145,11 @@ void InsertImpostorsVisitor::insertImpostors()
|
||||
for(unsigned int ci=0;ci<lod->getNumChildren();++ci)
|
||||
{
|
||||
impostor->addChild(lod->getChild(ci));
|
||||
}
|
||||
|
||||
for(unsigned int ri=0;ri<lod->getNumRanges();++ri)
|
||||
{
|
||||
impostor->setRange(ri,lod->getRange(ri));
|
||||
impostor->setRange(ci,lod->getMinRange(ci),lod->getMaxRange(ci));
|
||||
}
|
||||
|
||||
impostor->setCenter(lod->getCenter());
|
||||
impostor->setCenterMode(lod->getCenterMode());
|
||||
|
||||
// impostor specfic settings.
|
||||
impostor->setImpostorThresholdToBound(_impostorThresholdRatio);
|
||||
|
||||
@@ -24,13 +24,12 @@ using namespace osgUtil;
|
||||
void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
{
|
||||
|
||||
// temporarily commented out to prevent problems with combining FLT lod's inapporpriately,
|
||||
// if (options & COMBINE_ADJACENT_LODS)
|
||||
// {
|
||||
// CombineLODsVisitor clv;
|
||||
// node->accept(clv);
|
||||
// clv.combineLODs();
|
||||
// }
|
||||
if (options & COMBINE_ADJACENT_LODS)
|
||||
{
|
||||
CombineLODsVisitor clv;
|
||||
node->accept(clv);
|
||||
clv.combineLODs();
|
||||
}
|
||||
|
||||
if (options & FLATTEN_STATIC_TRANSFORMS)
|
||||
{
|
||||
@@ -560,7 +559,7 @@ void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& m
|
||||
// adjust ranges to new scale.
|
||||
for(unsigned int i=0;i<lod->getNumRanges();++i)
|
||||
{
|
||||
lod->setRange(i,lod->getRange(i)*ratio);
|
||||
lod->setRange(i,lod->getMinRange(i)*ratio,lod->getMaxRange(i)*ratio);
|
||||
}
|
||||
|
||||
lod->dirtyBound();
|
||||
@@ -968,14 +967,7 @@ void Optimizer::CombineLODsVisitor::combineLODs()
|
||||
osg::LOD* lod = dynamic_cast<osg::LOD*>(child);
|
||||
if (lod)
|
||||
{
|
||||
if (lod->getNumRanges()-1==lod->getNumChildren())
|
||||
{
|
||||
lodChildren.insert(lod);
|
||||
}
|
||||
else
|
||||
{
|
||||
// wonky LOD, numRanges should = numChildren+1
|
||||
}
|
||||
lodChildren.insert(lod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,29 +975,29 @@ void Optimizer::CombineLODsVisitor::combineLODs()
|
||||
{
|
||||
osg::BoundingBox bb;
|
||||
LODSet::iterator lod_itr;
|
||||
float smallestRadius=FLT_MAX;
|
||||
for(lod_itr=lodChildren.begin();
|
||||
lod_itr!=lodChildren.end();
|
||||
++lod_itr)
|
||||
{
|
||||
|
||||
float r = (*lod_itr)->getBound().radius();
|
||||
if (r>=0 && r<smallestRadius) smallestRadius = r;
|
||||
bb.expandBy((*lod_itr)->getCenter());
|
||||
}
|
||||
if (bb.radius()<1e-2)
|
||||
if (bb.radius()<smallestRadius*0.1f)
|
||||
{
|
||||
typedef std::pair<float,float> RangePair;
|
||||
typedef std::multimap<RangePair,osg::Node*> RangeMap;
|
||||
RangeMap rangeMap;
|
||||
float maxRange = 0.0f;
|
||||
for(lod_itr=lodChildren.begin();
|
||||
lod_itr!=lodChildren.end();
|
||||
++lod_itr)
|
||||
{
|
||||
|
||||
osg::LOD* lod = *lod_itr;
|
||||
for(unsigned int i=0;i<lod->getNumRanges()-1;++i)
|
||||
for(unsigned int i=0;i<lod->getNumRanges();++i)
|
||||
{
|
||||
if (maxRange<lod->getRange(i+1)) maxRange = lod->getRange(i+1);
|
||||
rangeMap.insert(RangeMap::value_type(RangePair(lod->getRange(i),lod->getRange(i+1)),lod->getChild(i)));
|
||||
rangeMap.insert(RangeMap::value_type(RangePair(lod->getMinRange(i),lod->getMaxRange(i)),lod->getChild(i)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1020,10 +1012,9 @@ void Optimizer::CombineLODsVisitor::combineLODs()
|
||||
c_itr!=rangeMap.end();
|
||||
++c_itr,++i)
|
||||
{
|
||||
newLOD->setRange(i,c_itr->first.first);
|
||||
newLOD->setRange(i,c_itr->first.first,c_itr->first.second);
|
||||
newLOD->addChild(c_itr->second);
|
||||
}
|
||||
newLOD->setRange(i,maxRange);
|
||||
|
||||
// add LOD into parent.
|
||||
group->addChild(newLOD);
|
||||
|
||||
Reference in New Issue
Block a user