StateGraph* prev_rg = previous->_parent; //上一个渲染叶的状态节点
StateGraph* prev_rg_parent = prev_rg->_parent; //上一个渲染叶所在的状态节点的父节点
StateGraph* rg = _parent; 当前叶子所在的状态节点
if (prev_rg_parent!=rg->_parent) //如果前一个渲染叶和现在的渲染叶所在的状态节点的父节点不是同一个节点,需要从当前状态节点重新收集状态属性
{
StateGraph::moveStateGraph(state,prev_rg_parent,rg->_parent);//重新收集状态属性
// send state changes and matrix changes to OpenGL.
state.apply(rg->getStateSet());
}
else if (rg!=prev_rg)
{
// send state changes and matrix changes to OpenGL.
state.apply(rg->getStateSet());
}
static inline void moveStateGraph(osg::State& state,StateGraph* sg_curr,StateGraph* sg_new)
{
if (sg_new==sg_curr || sg_new==NULL) return;
if (sg_curr==NULL)
{
// use return path to trace back steps to sg_new.
std::vector<StateGraph*> return_path; //收集当前渲染叶的状态集
// need to pop back root render graph.
do
{
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
} while (sg_new);遍历到根节点,把当前节点到根节点的所有状态节点压入堆栈
for(std::vector<StateGraph*>::reverse_iterator itr=return_path.rbegin();
itr!=return_path.rend();
++itr)
{
StateGraph* rg = (*itr);
if (rg->getStateSet()) state.pushStateSet(rg->getStateSet());//把收集的节点压入堆栈
}
return;
}
// first handle the typical case which is two state groups
// are neighbours.
if (sg_curr->_parent==sg_new->_parent) //当前stateGraph节点和上一个stateGraph节点的父节点是同一个节点
{
// state has changed so need to pop old state.
if (sg_curr->getStateSet()) state.popStateSet();//把上一个节点的stateset弹出
// and push new state.
if (sg_new->getStateSet()) state.pushStateSet(sg_new->getStateSet());//压入当前stateset
return;
}
// need to pop back up to the same depth as the new state group.
while (sg_curr->_depth>sg_new->_depth))//如果新的层数比当前层数小,由向上遍历,至到层数相同
{
if (sg_curr->getStateSet()) state.popStateSet();
sg_curr = sg_curr->_parent;
}
// use return path to trace back steps to sg_new.
std::vector<StateGraph*> return_path;
// need to pop back up to the same depth as the curr state group.
while (sg_new->_depth>sg_curr->_depth {//和上面情况相反,用return_path记住sg_new当前路径到相同节点的路径
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
}
// now pop back up both parent paths until they agree.
// DRT - 10/22/02
// should be this to conform with above case where two StateGraph
// nodes have the same parent
while (sg_curr != sg_new)//如果不是同一个节点,则一直向根节点遍历,同时保留当前新节点的路径
{
if (sg_curr->getStateSet()) state.popStateSet();
sg_curr = sg_curr->_parent;
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
}
for(std::vector<StateGraph*>::reverse_iterator itr=return_path.rbegin();//已经向上遍历到同一个节点,然后pushStateSet()
itr!=return_path.rend();
++itr)
{
StateGraph* rg = (*itr);
if (rg->getStateSet()) state.pushStateSet(rg->getStateSet());
}
}