2015-06-01 70 views
1

有一個Geode,其幾何是一個球,其上面分配有一個MatrixTransform()。它的回調函數使它下降。當球與地面相交時,我希望將其從場景中移除。如何從其回調函數中刪除節點?

下面的代碼拋出異常:

//inside the ball's callback 

virtual void operator()(osg::Node* node ,osg::NodeVisitor* nv) 
{ 
    using namespace osg; 
    MatrixTransform* matrix_node = dynamic_cast<MatrixTransform*>(node); 
    Matrix matrix = matrix_node->getMatrix(); 

    velocity += Vec3(0, 0, -0.002); 

    matrix.postMultTranslate(velocity); 

    matrix_node->setMatrix(matrix); 

    Vec3 now_position = start_position * matrix; 

    osgUtil::IntersectVisitor ivXY; 

    osg::ref_ptr<osg::LineSegment> lineXY = new osg::LineSegment(now_position, now_position+velocity); 

    ivXY.addLineSegment(lineXY); 

    GAME.main_camera->m_pHostViewer->getSceneData()->accept(ivXY) ; 
    if(ivXY.hits()) 
    { 
     node->getParent(0)->removeChild(node); 
    } 
    return; 
} 

如何正確做呢?謝謝!

+0

不會分配'NULL'回調工作?類似'node-> addWhateverCallback(0)' –

回答

1

這是OSG的Group class(從MatrixTransform繼承)的摘錄:

void Group::traverse(NodeVisitor& nv) 
{ 
     for(NodeList::iterator itr=_children.begin(); 
     itr!=_children.end(); 
     ++itr) 
    { 
     (*itr)->accept(nv); 
    } 
} 

bool Group::removeChild(Node *child) 
{ 
    unsigned int pos = getChildIndex(child); 
    if (pos<_children.size()) return removeChildren(pos,1); 
    else return false; 
} 

您的代碼(這是從橫向調用),因爲迭代器獲取循環的中間無效可能會拋出異常,當調用removeChild時。要刪除節點,您必須至少等到節點回調返回。

要解決這個問題,我只需使用節點掩碼來控制球是否顯示。最初,將球節點掩碼設置爲「可見」值。當球擊中地面時,將節點掩碼設置爲「隱藏」值。該節點不會被遍歷/渲染,但仍然會在內存中。

如果存在內存問題,可以將代碼移動到父節點或更新遍歷之外(例如,使用修改後的Viewer :: run方法)。

+1

謝謝,最後我們通過使用隊列並從回調之外刪除節點來解決此問題。感謝您告訴我關於節點掩碼的信息。 – DarkZero