void SceneTree::update( dp::sg::ui::ViewStateSharedPtr const& vs ) { ObjectTreeIndexSet dirtyGeoNodes; m_geoNodeObserver->popDirtyGeoNodes(dirtyGeoNodes); for ( ObjectTreeIndexSet::const_iterator it = dirtyGeoNodes.begin(); it != dirtyGeoNodes.end(); ++it ) { drawableInstanceUpdate( *it ); } { dp::util::ProfileEntry p("Update TransformTree"); updateTransformTree( vs ); } { dp::util::ProfileEntry p("Update ObjectTree"); updateObjectTree( vs ); } }
void SceneTree::updateObjectTree(dp::sg::core::CameraSharedPtr const& camera, float lodRangeScale) { // // first step: update node-local information // // update dirty object hints & masks { ObjectObserver::NewCacheData cd; m_objectObserver->popNewCacheData( cd ); ObjectObserver::NewCacheData::const_iterator it, it_end = cd.end(); for( it=cd.begin(); it!=it_end; ++it ) { ObjectTreeNode& node = m_objectTree[ it->first ]; node.m_localHints = it->second.m_hints; node.m_localMask = it->second.m_mask; m_objectTree.markDirty( it->first, ObjectTreeNode::DEFAULT_DIRTY ); } } // update dirty switch information ObjectTreeIndexSet dirtySwitches; m_switchObserver->popDirtySwitches( dirtySwitches ); if( !dirtySwitches.empty() ) { ObjectTreeIndexSet::iterator it, it_end = dirtySwitches.end(); for( it=dirtySwitches.begin(); it!=it_end; ++it ) { ObjectTreeIndex index = *it; SwitchSharedPtr ssp = m_objectTree.m_switchNodes[ index ].lock(); DP_ASSERT( ssp ); ObjectTreeIndex childIndex = m_objectTree[index].m_firstChild; // counter for the i-th child size_t i = 0; while( childIndex != ~0 ) { ObjectTreeNode& childNode = m_objectTree[childIndex]; DP_ASSERT( childNode.m_parentIndex == index ); bool newActive = ssp->isActive( dp::checked_cast<unsigned int>(i) ); if ( childNode.m_localActive != newActive ) { childNode.m_localActive = newActive; m_objectTree.markDirty( childIndex, ObjectTreeNode::DEFAULT_DIRTY ); } childIndex = childNode.m_nextSibling; ++i; } } } // update all lods if( !m_objectTree.m_LODs.empty() ) { const Mat44f& worldToView = camera->getWorldToViewMatrix(); std::map< ObjectTreeIndex, LODWeakPtr >::iterator it, it_end = m_objectTree.m_LODs.end(); for( it = m_objectTree.m_LODs.begin(); it != it_end; ++it ) { ObjectTreeIndex index = it->first; const ObjectTreeNode& node = m_objectTree[ index ]; Mat44f const & modelToWorld = m_transformTree.getWorldMatrix(node.m_transform); const Mat44f modelToView = modelToWorld * worldToView; ObjectTreeIndex activeIndex = it->second.lock()->getLODToUse( modelToView, lodRangeScale ); ObjectTreeIndex childIndex = m_objectTree[index].m_firstChild; // counter for the i-th child size_t i = 0; while( childIndex != ~0 ) { ObjectTreeNode& childNode = m_objectTree[childIndex]; DP_ASSERT( childNode.m_parentIndex == index ); bool newActive = activeIndex == i; if ( childNode.m_localActive != newActive ) { childNode.m_localActive = newActive; m_objectTree.markDirty( childIndex, ObjectTreeNode::DEFAULT_DIRTY ); } childIndex = childNode.m_nextSibling; ++i; } } } // // second step: update resulting node-world information // UpdateObjectVisitor objectVisitor( m_objectTree, this ); PreOrderTreeTraverser<ObjectTree, UpdateObjectVisitor> objectTraverser; objectTraverser.processDirtyList( m_objectTree, objectVisitor, ObjectTreeNode::DEFAULT_DIRTY ); m_objectTree.m_dirtyObjects.clear(); }