Example #1
0
      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();
      }
Example #2
0
      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();
      }