void copy( VertexAttributeSetSharedPtr const& src, VertexAttributeSetSharedPtr const& dst )
      {
        if ( src != dst )
        {
          dst->setName( src->getName() );
          dst->setAnnotation( src->getAnnotation() );
          dst->setHints( src->getHints() );
          dst->setUserData( src->getUserData() );

          for ( unsigned int i=0 ; i<2*static_cast<unsigned int>(VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT) ; ++i )
          {
            VertexAttributeSet::AttributeID id = static_cast<VertexAttributeSet::AttributeID>(i);
            if ( src->getSizeOfVertexData( id ) )
            {
              DP_ASSERT( ( src->getOffsetOfVertexData( id ) == 0 ) && src->isContiguousVertexData( id ) );
              dst->setVertexData( id, src->getSizeOfVertexData( id ), src->getTypeOfVertexData( id )
                                , src->getVertexBuffer( id ), src->getOffsetOfVertexData( id )
                                , src->getStrideOfVertexData( id ), src->getNumberOfVertexData( id ) );
              dst->setEnabled( id, src->isEnabled( id ) );
              if ( id >= VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT )
              {
                dst->setNormalizeEnabled( id, src->isNormalizeEnabled( id ) );
              }
            }
          }
        }
      }
Beispiel #2
0
      void deIndexPrimitiveT( Primitive * p )
      {
        Buffer::DataReadLock indexBuffer( p->getIndexSet()->getBuffer() );

        VertexAttributeSetSharedPtr const& vas = p->getVertexAttributeSet();
        unsigned int nov = vas->getNumberOfVertices();
        unsigned int noi = p->getIndexSet()->getNumberOfIndices();
        if (    ( nov != noi )
            ||  ! checkFlat( (const T *)indexBuffer.getPtr(), noi )
            ||  ! checkTrivial( (const T *)indexBuffer.getPtr(), noi ) )
        {
          VertexAttributeSetSharedPtr newVASH = VertexAttributeSet::create();
          for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ )
          {
            if ( vas->getSizeOfVertexData(i) )
            {
              Buffer::DataReadLock indexBufferLock( p->getIndexSet()->getBuffer() );
              const T * idxPtr = indexBufferLock.getPtr<T>();
              dp::DataType type = vas->getTypeOfVertexData(i);
              unsigned int size = dp::checked_cast<unsigned int>(vas->getSizeOfVertexData(i) * dp::getSizeOf( type ));
              unsigned int stride = vas->getStrideOfVertexData(i);
              DP_ASSERT( size <= stride );
              unsigned int numIndices = p->getIndexSet()->getNumberOfIndices();

              BufferHostSharedPtr newVertexBuffer = BufferHost::create();
              newVertexBuffer->setSize( numIndices * size );
              {
                Buffer::DataReadLock oldBufferLock( vas->getVertexData( i ) );
                const unsigned char * oldBuffPtr = oldBufferLock.getPtr<unsigned char>();

                Buffer::DataWriteLock newBufferLock( newVertexBuffer, Buffer::MAP_WRITE );
                unsigned char * newBuffPtr = newBufferLock.getPtr<unsigned char>();

                for ( unsigned int idx=0 ; idx < numIndices ; idx++ )
                {
                  memcpy( newBuffPtr, oldBuffPtr + stride * idxPtr[idx], size );
                  newBuffPtr += size;
                }
              }

              newVASH->setVertexData( i, vas->getSizeOfVertexData(i), type, newVertexBuffer, 0, stride, numIndices );

              // inherit enable states from source attrib
              // normalize-enable state only meaningful for generic aliases!
              newVASH->setEnabled(i, vas->isEnabled(i)); // conventional
              newVASH->setEnabled(i+16, vas->isEnabled(i+16)); // generic
              newVASH->setNormalizeEnabled(i+16, vas->isNormalizeEnabled(i+16)); // only generic
            }
          }
          p->setVertexAttributeSet( newVASH );
        }
      }
      void copySelectedVertices( const VertexAttributeSetSharedPtr & from, const VertexAttributeSetSharedPtr & to
                               , std::vector<std::vector<unsigned int> > &indices )
      {
        // indexMap below is intended to hold vertex indices, which should not exceed 32-bit precision by definition!
        std::vector<unsigned int> indexMap( from->getNumberOfVertices(), ~0 );
        std::vector<unsigned int> iFrom; iFrom.reserve(from->getNumberOfVertices());
        for ( size_t i=0 ; i<indices.size() ; i++ )
        {
          for ( size_t j=0 ; j<indices[i].size() ; j++ )
          {
            if ( indexMap[indices[i][j]] == ~0 )
            {
              indexMap[indices[i][j]] = dp::checked_cast<unsigned int>(iFrom.size());
              iFrom.push_back(indices[i][j]);
            }
          }
        }

        for ( unsigned int slot=0 ; slot<static_cast<unsigned int>(VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT) ; slot++ )
        {
          VertexAttributeSet::AttributeID id = static_cast<VertexAttributeSet::AttributeID>(slot);
          if ( from->getSizeOfVertexData( id ) )
          {
            BufferSharedPtr oldData = from->getVertexBuffer(id);
            Buffer::DataReadLock lock( oldData );

            unsigned int size = from->getSizeOfVertexData( id );
            dp::DataType type = from->getTypeOfVertexData( id );

            to->setVertexData( id, NULL, &iFrom[0], size, type, lock.getPtr()
                             , from->getStrideOfVertexData( id )
                             , dp::checked_cast<unsigned int>(iFrom.size()) );

            // inherit enable states from source id
            // normalize-enable state only meaningful for generic aliases!
            to->setEnabled(id, from->isEnabled(id)); // conventional

            id = static_cast<VertexAttributeSet::AttributeID>(slot+16);    // generic
            to->setEnabled(id, from->isEnabled(id));
            to->setNormalizeEnabled(id, from->isNormalizeEnabled(id));
          }
        }

        for ( size_t i=0 ; i<indices.size() ; i++ )
        {
          for ( size_t j=0 ; j<indices[i].size() ; j++ )
          {
            indices[i][j] = indexMap[indices[i][j]];
          }
        }
      }
Beispiel #4
0
      void UnifyTraverser::handleVertexAttributeSet( VertexAttributeSet * p )
      {
        pair<set<const void *>::iterator,bool> pitb = m_objects.insert( p );
        if ( pitb.second )
        {
          OptimizeTraverser::handleVertexAttributeSet( p );
          // Check if optimization is allowed
          if ( optimizationAllowed( p->getSharedPtr<VertexAttributeSet>() ) && (m_unifyTargets & UT_VERTICES) )
          {
            VertexAttributeSetSharedPtr vas = p->getSharedPtr<VertexAttributeSet>();
            unsigned int n = p->getNumberOfVertices();

            //  handle VAS with more than one vertex only
            if ( 1 < n )
            {
              // ***************************************************************
              // the algorithm currently only works for float-typed vertex data!
              // ***************************************************************
              for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ )
              {
                unsigned int type = p->getTypeOfVertexData(i);
                if (  type != dp::DT_UNKNOWN // no data is ok!
                   && type != dp::DT_FLOAT_32 )  
                {
                  DP_ASSERT( !"This algorithm currently only works for float-typed vertex data!" );
                  return; 
                }
              }
              // ***************************************************************
              // ***************************************************************

              //  count the dimension of the VertexAttributeSet
              unsigned int  dimension = 0;
              for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ )
              {
                if ( p->getNumberOfVertexData( i ) )
                {
                  dimension += p->getSizeOfVertexData( i );
                }
              }

              vector<float> valueDataIn( n * dimension );
              vector<float*> valuesIn( n );
              for ( size_t i=0, j=0 ; i<valuesIn.size() ; i++, j+=dimension )
              {
                valuesIn[i] = &valueDataIn[j];
              }

              //  fill valuesIn with the vertex attribute data
              for ( unsigned int i=0, j=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ )
              {
                if ( p->getNumberOfVertexData( i ) != 0 )
                {
                  unsigned int dim = p->getSizeOfVertexData( i );
                  Buffer::ConstIterator<float>::Type vad = p->getVertexData<float>( i );
                  for ( unsigned int k=0 ; k<n ; k++ )
                  {
                    const float *value = &vad[k];
                    for ( unsigned int l=0 ; l<dim ; l++ )
                    {
                      valuesIn[k][j+l] = value[l];
                    }
                  }
                  j += dim;
                }
              }

              VUTOctreeNode * octree = new VUTOctreeNode();
              octree->init( boundingBox<3, float, Buffer::ConstIterator<Vec3f>::Type >( p->getVertices(), p->getNumberOfVertices() )
                          , std::max( (unsigned int)32, (unsigned int)pow( p->getNumberOfVertices(), 0.25 ) ) );
              unsigned int count = dp::checked_cast<unsigned int>(valuesIn.size());
              for ( unsigned int i=0 ; i<count ; i++ )
              {
                octree->addVertex( valuesIn, i, dimension, m_epsilon );
              }
              unsigned int pointCount = octree->getNumberOfPoints();

              //  if there are less points only
              if ( pointCount < n )
              {
                //  initialize the index mapping to undefined
                vector<unsigned int>  indexMap( n );
                for ( unsigned int i=0 ; i<n ; i++ )
                {
                  indexMap[i] = ~0;
                }

                //  create the vector of vertex attribute valuesIn
                vector<float> valueDataOut( pointCount * dimension );
                vector<float*> valuesOut( pointCount );
                for ( size_t i=0, j=0 ; i<valuesOut.size() ; i++, j+=dimension )
                {
                  valuesOut[i] = &valueDataOut[j];
                }

                // fill valuesOut and the indexMap
                unsigned int index = 0;
                octree->mapValues( valuesIn, valuesOut, dimension, indexMap, index );
                delete octree;

                //  create a new VertexAttributeSet with the condensed data
                VertexAttributeSetSharedPtr newVAS = VertexAttributeSet::create();
                for ( unsigned int i=0, j=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ )
                {
                  if ( p->getNumberOfVertexData( i ) )
                  {
                    unsigned int dim = p->getSizeOfVertexData( i );
                    vector<float> vad( dim * valuesOut.size() );
                    for ( size_t k=0 ; k<valuesOut.size() ; k++ )
                    {
                      for ( unsigned int l=0 ; l<dim ; l++ )
                      {
                        vad[dim*k+l] = valuesOut[k][j+l];
                      }
                    }
                    newVAS->setVertexData( i, dim, dp::DT_FLOAT_32, &vad[0], 0, dp::checked_cast<unsigned int>(vad.size()/dim) );

                    // inherit enable states from source attrib
                    // normalize-enable state only meaningful for generic aliases!
                    newVAS->setEnabled(i, p->isEnabled(i)); // conventional
                    newVAS->setEnabled(i+16, p->isEnabled(i+16)); // generic
                    newVAS->setNormalizeEnabled(i+16, p->isNormalizeEnabled(i+16)); // generic only!
                    j += dim;
                  }
                }

                DP_ASSERT( m_vasReplacements.find( vas ) == m_vasReplacements.end() );
                m_vasReplacements[vas] = VASReplacement( newVAS, indexMap );
              }
              else
              {
                delete octree;
              }
            }
          }
        }
      }