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:
Robert Osfield
2002-10-06 20:33:13 +00:00
parent 84332f5b77
commit 70861ef70e
19 changed files with 240 additions and 195 deletions

View File

@@ -32,6 +32,21 @@ void CollectOccludersVisitor::reset()
CullStack::reset();
}
float CollectOccludersVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODBias) const
{
if (withLODBias) return (pos-getEyeLocal()).length()*getLODBias();
else return (pos-getEyeLocal()).length();
}
float CollectOccludersVisitor::getDistanceFromEyePoint(const Vec3& pos, bool withLODBias) const
{
const Matrix& matrix = *_modelviewStack.back();
float dist = -(pos[0]*matrix(0,2)+pos[1]*matrix(1,2)+pos[2]*matrix(2,2)+matrix(3,2));
if (withLODBias) return dist*getLODBias();
else return dist*getLODBias();
}
void CollectOccludersVisitor::apply(osg::Node& node)
{
if (isCulled(node)) return;
@@ -91,14 +106,10 @@ void CollectOccludersVisitor::apply(osg::LOD& node)
{
if (isCulled(node)) return;
int eval = node.evaluate(getEyeLocal(),_LODBias);
if (eval<0) return;
// push the culling mode.
pushCurrentMask();
//notify(INFO) << "selecting child "<<eval<< std::endl;
handle_cull_callbacks_and_accept(node,node.getChild(eval));
handle_cull_callbacks_and_traverse(node);
// pop the culling mode.
popCurrentMask();

View File

@@ -6,9 +6,9 @@ using namespace osg;
LOD::LOD(const LOD& lod,const CopyOp& copyop):
Group(lod,copyop),
_rangeList(lod._rangeList),
_rangeList2(lod._rangeList2),
_center(lod._center)
_centerMode(lod._centerMode),
_userDefinedCenter(lod._userDefinedCenter),
_rangeList(lod._rangeList)
{
}
@@ -21,42 +21,51 @@ void LOD::traverse(NodeVisitor& nv)
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
break;
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
if (_children.size()!=0) _children.front()->accept(nv);
break;
{
float distance = nv.getDistanceToEyePoint(getCenter(),true);
unsigned int numChildren = _children.size();
if (_rangeList.size()<numChildren) numChildren=_rangeList.size();
for(unsigned int i=0;i<numChildren;++i)
{
if (_rangeList[i].first<=distance && distance<_rangeList[i].second)
{
_children[i]->accept(nv);
}
}
break;
}
default:
break;
}
}
void LOD::setRange(unsigned int index, float range)
bool LOD::addChild( Node *child )
{
if (index<_rangeList.size()) _rangeList[index] = range;
else while (index>=_rangeList.size()) _rangeList.push_back(range);
if (index<_rangeList2.size()) _rangeList2[index] = range*range;
else while (index>=_rangeList2.size()) _rangeList2.push_back(range*range);
}
int LOD::evaluateLODChild(const Vec3& eye_local, float bias) const
{
// For cache coherency, use _rangeList2 exclusively
if (_rangeList2.empty()) return -1;
// Test distance-squared against the stored array of squared ranges
float LODRange = (eye_local-_center).length2()*bias;
if (LODRange<_rangeList2[0]) return -1;
unsigned int end_marker = _rangeList2.size()-1;
if (end_marker>_children.size()) end_marker=_children.size();
for(unsigned int i=0;i<end_marker;++i)
if (Group::addChild(child))
{
if (LODRange<_rangeList2[i+1])
{
return i;
}
float maxRange = 0.0f;
if (!_rangeList.empty()) maxRange=_rangeList.back().second;
if (_children.size()>_rangeList.size()) _rangeList.resize(_children.size(),MinMaxPair(maxRange,maxRange));
return true;
}
return -1;
return false;
}
bool LOD::removeChild( Node *child )
{
// find the child's position.
unsigned int pos=findChildNo(child);
if (pos==_children.size()) return false;
_rangeList.erase(_rangeList.begin()+pos);
return Group::removeChild(child);
}
void LOD::setRange(unsigned int childNo, float min,float max)
{
if (childNo>=_rangeList.size()) _rangeList.resize(childNo+1,MinMaxPair(min,min));
_rangeList[childNo].first=min;
_rangeList[childNo].second=max;
}

View File

@@ -53,11 +53,7 @@ bool Switch::addChild( Node *child )
bool Switch::removeChild( Node *child )
{
// find the child's position.
unsigned int pos=0;
for (;pos<_children.size();++pos)
{
if (_children[pos]==child) break;
}
unsigned int pos=findChildNo(child);
if (pos==_children.size()) return false;
_values.erase(_values.begin()+pos);
@@ -74,11 +70,7 @@ void Switch::setValue(unsigned int pos,bool value)
void Switch::setValue(const Node* child,bool value)
{
// find the child's position.
unsigned int pos=0;
for (;pos<_children.size();++pos)
{
if (_children[pos]==child) break;
}
unsigned int pos=findChildNo(child);
if (pos==_children.size()) return;
_values[pos]=value;
@@ -93,11 +85,7 @@ bool Switch::getValue(unsigned int pos) const
bool Switch::getValue(const Node* child) const
{
// find the child's position.
unsigned int pos=0;
for (;pos<_children.size();++pos)
{
if (_children[pos]==child) break;
}
unsigned int pos=findChildNo(child);
if (pos==_children.size()) return false;
return _values[pos];