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(); }
void SceneTree::updateTransformTree( dp::sg::ui::ViewStateSharedPtr const& vs ) { // // first step: update node local information // // update dirty transforms from transform observer { const TransformObserver::DirtyPayloads& cd = m_transformObserver->getDirtyPayloads(); TransformObserver::DirtyPayloads::const_iterator it, it_end = cd.end(); for( it = cd.begin(); it != it_end; ++it ) { TransformTreeIndex index = (*it)->m_index; TransformTreeNode& node = m_transformTree[index]; DP_ASSERT( node.m_transform != nullptr ); const Trafo& t = node.m_transform->getTrafo(); node.m_localMatrix = t.getMatrix(); const Vec3f& s( t.getScaling() ); node.setLocalBits( TransformTreeNode::ISMIRRORTRANSFORM, s[0]*s[1]*s[2] < 0.0f ); m_transformTree.markDirty( index, TransformTreeNode::DEFAULT_DIRTY ); // mark the transform's corresponding object tree node's bounding volume dirty DP_ASSERT( node.m_objectTreeIndex != ~0 ); (*it)->m_dirty = false; } m_transformObserver->clearDirtyPayloads(); } // update dynamic transforms { TransformTreeIndexSet::const_iterator it, it_end = m_dynamicTransformIndices.end(); for( it=m_dynamicTransformIndices.begin(); it!=it_end; ++it ) { TransformTreeIndex index = *it; TransformTreeNode& node = m_transformTree[index]; if( node.m_transform ) { Trafo t = node.m_transform->getTrafo(); node.m_localMatrix = t.getMatrix(); const Vec3f& s( t.getScaling() ); node.setLocalBits( TransformTreeNode::ISMIRRORTRANSFORM, s[0]*s[1]*s[2] < 0.0f ); } m_transformTree.markDirty( index, TransformTreeNode::DEFAULT_DIRTY ); } } // // second step: update resulting node-world information // m_changedTransforms.clear(); UpdateTransformVisitor visitor( m_transformTree, *this, vs->getCamera(), m_changedTransforms ); PreOrderTreeTraverser<TransformTree, UpdateTransformVisitor> traverser; traverser.processDirtyList( m_transformTree, visitor, TransformTreeNode::DEFAULT_DIRTY); m_transformTree.m_dirtyObjects.clear(); }