void setupScene_MultiDrawElements()
  {
    ref<Geometry> torus1 = vl::makeTorus( vec3(-10, -9, 0), 8.0f, 1.0f, 20, 20 );
    ref<Geometry> torus2 = vl::makeTorus( vec3(  0, -9, 0), 8.0f, 2.0f, 10, 10 );
    ref<Geometry> torus3 = vl::makeTorus( vec3(+10, -9, 0), 8.0f, 3.0f, 7, 7 );

    // merge vertices
    ref<ArrayFloat3> vert = new ArrayFloat3;
    ref<ArrayFloat3> torus1_vert = vl::cast<ArrayFloat3>(torus1->vertexArray());
    ref<ArrayFloat3> torus2_vert = vl::cast<ArrayFloat3>(torus2->vertexArray());
    ref<ArrayFloat3> torus3_vert = vl::cast<ArrayFloat3>(torus3->vertexArray());

    vert->resize( torus1_vert->size() + torus2_vert->size() + torus3_vert->size() );
    memcpy( vert->ptr(), torus1_vert->ptr(), torus1_vert->bytesUsed() );
    memcpy( vert->ptr() + torus1_vert->bytesUsed(), torus2_vert->ptr(), torus2_vert->bytesUsed() );
    memcpy( vert->ptr() + torus1_vert->bytesUsed() + torus2_vert->bytesUsed(), torus3_vert->ptr(), torus3_vert->bytesUsed() );

    // merge indices
    ref<MultiDrawElementsUInt> mde = new MultiDrawElementsUInt(PT_QUADS);
    ref<DrawCall> torus1_dc = torus1->drawCalls()->at(0);
    ref<DrawCall> torus2_dc = torus2->drawCalls()->at(0);
    ref<DrawCall> torus3_dc = torus3->drawCalls()->at(0);

    int torus1_index_count = (int)torus1_dc->countIndices();
    int torus2_index_count = (int)torus2_dc->countIndices();
    int torus3_index_count = (int)torus3_dc->countIndices();
    mde->indexBuffer()->resize( torus1_index_count + torus2_index_count + torus3_index_count );

    MultiDrawElementsUInt::index_type* p_idx = mde->indexBuffer()->begin();
    for( IndexIterator it = torus1_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx )
      *p_idx = it.index();

    for( IndexIterator it = torus2_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx )
      *p_idx = it.index() + (int)torus1_vert->size();

    for( IndexIterator it = torus3_dc->indexIterator(); it.hasNext(); it.next(), ++p_idx )
      *p_idx = it.index() + (int)torus1_vert->size() + (int)torus2_vert->size();

    VL_CHECK(p_idx == mde->indexBuffer()->end());

    // define how many indices for each draw call
    GLsizei count_vector[] = { torus1_index_count, torus2_index_count, torus3_index_count };
    mde->setCountVector( count_vector, 3 );

    ref<Geometry> geom = new Geometry;
    geom->setVertexArray( vert.get() );
    geom->drawCalls()->push_back( mde.get() );

    // compute normals must be done after the draw calls have been added.
    geom->computeNormals();

    ref<Effect> fx = new Effect;
    fx->shader()->setRenderState( new Light, 0 );
    fx->shader()->enable(vl::EN_LIGHTING);
    fx->shader()->enable(vl::EN_DEPTH_TEST);
    fx->shader()->gocMaterial()->setDiffuse( vl::pink );

    sceneManager()->tree()->addActor( geom.get(), fx.get(), NULL );
  }
 /** Counts the number of virtual indices of a DrawCall. */
 int countIndices() const
 {
   int count = 0;
   for( IndexIterator it = indexIterator(); !it.isEnd(); it.next() )
     count++;
   return count;
 }
Example #3
0
 int NamespaceDetails::_catalogFindIndexByName(OperationContext* txn,
                                               const Collection* coll,
                                               const StringData& name,
                                               bool includeBackgroundInProgress) const {
     IndexIterator i = ii(includeBackgroundInProgress);
     while( i.more() ) {
         const BSONObj obj = coll->docFor(txn, i.next().info.toRecordId());
         if ( name == obj.getStringField("name") )
             return i.pos()-1;
     }
     return -1;
 }
//-----------------------------------------------------------------------------
void DoubleVertexRemover::removeDoubles(Geometry* geom)
{
  mMapNewToOld.clear();
  mMapOldToNew.clear();

  std::vector<unsigned int> verti;
  verti.resize(geom->vertexArray()->size());
  mMapOldToNew.resize(verti.size());
  for(unsigned int i=0; i<verti.size(); ++i)
  {
    verti[i] = i;
    mMapOldToNew[i] = 0xFFFFFFFF;
  }
  mMapNewToOld.reserve(verti.size());

  std::sort(verti.begin(), verti.end(), CompareVertex(geom));

  if (verti.empty())
    return;

  unsigned int unique_vert_idx = 0;
  for(unsigned i=1; i<verti.size(); ++i)
  {
    if ( !CompareVertex(geom).equals(verti[unique_vert_idx],verti[i]) )
    {
      for(unsigned j=unique_vert_idx; j<i; ++j)
        mMapOldToNew[verti[j]] = mMapNewToOld.size();
      mMapNewToOld.push_back(verti[unique_vert_idx]);
      unique_vert_idx = i;
    }
  }
  for(unsigned j=unique_vert_idx; j<verti.size(); ++j)
  {
    mMapOldToNew[verti[j]] = mMapNewToOld.size();
    mMapNewToOld.push_back(verti[unique_vert_idx]);
  }

  // regenerate vertices

  geom->regenerateVertices(mMapNewToOld);

  // regenerate DrawCall

  std::vector< ref<DrawCall> > draw_cmd;
  for(int idraw=0; idraw<geom->drawCalls()->size(); ++idraw)
    draw_cmd.push_back( geom->drawCalls()->at(idraw) );
  geom->drawCalls()->clear();

  for(size_t idraw=0; idraw<draw_cmd.size(); ++idraw)
  {
    ref<DrawElementsUInt> tris = new DrawElementsUInt( draw_cmd[idraw]->primitiveType() );
    geom->drawCalls()->push_back(tris.get());
    const int idx_count = draw_cmd[idraw]->countIndices();
    tris->indices()->resize(idx_count);
    int i=0;
    for(IndexIterator it = draw_cmd[idraw]->indexIterator(); !it.isEnd(); it.next(), ++i)
      tris->indices()->at(i) = mMapOldToNew[it.index()];
  }

  #if 0
    printf("DoubleVertexRemover = %d/%d, saved = %d, shrink=%.2f\n", (int)mMapNewToOld.size(), (int)verti.size(), (int)verti.size()-(int)mMapNewToOld.size(), (float)mMapNewToOld.size()/verti.size() );
  #endif
}