예제 #1
0
void ObjLoader::createGeometryInstances( GLMmodel* model,
                                         Program mesh_intersect,
                                         Program mesh_bbox )
{
  std::vector<GeometryInstance> instances;

  // Loop over all groups -- grab the triangles and material props from each group
  unsigned int triangle_count = 0u;
  unsigned int group_count = 0u;
  for ( GLMgroup* obj_group = model->groups;
        obj_group != 0;
        obj_group = obj_group->next, group_count++ ) {

    unsigned int num_triangles = obj_group->numtriangles;
    if ( num_triangles == 0 ) continue; 

    // Create vertex index buffers
    Buffer vindex_buffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_INT3, num_triangles );
    int3* vindex_buffer_data = static_cast<int3*>( vindex_buffer->map() );

    Buffer tindex_buffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_INT3, num_triangles );
    int3* tindex_buffer_data = static_cast<int3*>( tindex_buffer->map() );

    Buffer nindex_buffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_INT3, num_triangles );
    int3* nindex_buffer_data = static_cast<int3*>( nindex_buffer->map() );

    // TODO: Create empty buffer for mat indices, have obj_material check for zero length
    Buffer mbuffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_UNSIGNED_INT, num_triangles );
    unsigned int* mbuffer_data = static_cast<unsigned int*>( mbuffer->map() );

    // Create the mesh object
    Geometry mesh = _context->createGeometry();
    mesh->setPrimitiveCount( num_triangles );
    mesh->setIntersectionProgram( mesh_intersect);
    mesh->setBoundingBoxProgram( mesh_bbox );
    mesh[ "vertex_buffer" ]->setBuffer( _vbuffer );
    mesh[ "normal_buffer" ]->setBuffer( _nbuffer );
    mesh[ "texcoord_buffer" ]->setBuffer( _tbuffer );
    mesh[ "vindex_buffer" ]->setBuffer( vindex_buffer );
    mesh[ "tindex_buffer" ]->setBuffer( tindex_buffer );
    mesh[ "nindex_buffer" ]->setBuffer( nindex_buffer );
    mesh[ "material_buffer" ]->setBuffer( mbuffer );

    // Create the geom instance to hold mesh and material params
    GeometryInstance instance = _context->createGeometryInstance( mesh, &_material, &_material+1 );
    loadMaterialParams( instance, obj_group->material );
    instances.push_back( instance );

    for ( unsigned int i = 0; i < obj_group->numtriangles; ++i, ++triangle_count ) {

      unsigned int tindex = obj_group->triangles[i];
      int3 vindices;
      vindices.x = model->triangles[ tindex ].vindices[0] - 1; 
      vindices.y = model->triangles[ tindex ].vindices[1] - 1; 
      vindices.z = model->triangles[ tindex ].vindices[2] - 1; 
      assert( vindices.x <= static_cast<int>(model->numvertices) );
      assert( vindices.y <= static_cast<int>(model->numvertices) );
      assert( vindices.z <= static_cast<int>(model->numvertices) );
      
      int3 nindices;
      nindices.x = model->triangles[ tindex ].nindices[0] - 1; 
      nindices.y = model->triangles[ tindex ].nindices[1] - 1; 
      nindices.z = model->triangles[ tindex ].nindices[2] - 1; 
      assert( nindices.x <= static_cast<int>(model->numnormals) );
      assert( nindices.y <= static_cast<int>(model->numnormals) );
      assert( nindices.z <= static_cast<int>(model->numnormals) );

      int3 tindices;
      tindices.x = model->triangles[ tindex ].tindices[0] - 1; 
      tindices.y = model->triangles[ tindex ].tindices[1] - 1; 
      tindices.z = model->triangles[ tindex ].tindices[2] - 1; 
      assert( tindices.x <= static_cast<int>(model->numtexcoords) );
      assert( tindices.y <= static_cast<int>(model->numtexcoords) );
      assert( tindices.z <= static_cast<int>(model->numtexcoords) );

      vindex_buffer_data[ i ] = vindices;
      nindex_buffer_data[ i ] = nindices;
      tindex_buffer_data[ i ] = tindices;
      mbuffer_data[ i ] = 0; // See above TODO
    }

    vindex_buffer->unmap();
    tindex_buffer->unmap();
    nindex_buffer->unmap();
    mbuffer->unmap();
  }

  assert( triangle_count == model->numtriangles );
  
  // Set up group 
  _geometrygroup->setChildCount( static_cast<unsigned int>(instances.size()) );
  Acceleration acceleration = _context->createAcceleration("Sbvh","Bvh");
  acceleration->setProperty( "vertex_buffer_name", "vertex_buffer" );
  acceleration->setProperty( "index_buffer_name", "vindex_buffer" );
  _geometrygroup->setAcceleration( acceleration );
  acceleration->markDirty();


  for ( unsigned int i = 0; i < instances.size(); ++i )
    _geometrygroup->setChild( i, instances[i] );
}
예제 #2
0
void MeshViewer::initGeometry()
{
  m_geometry_group = m_context->createGeometryGroup();

  if( ObjLoader::isMyFile( m_filename.c_str() ) ) {
    // Load OBJ model 
    ObjLoader* loader = 0;
    if( m_shade_mode == SM_NORMAL || m_shade_mode == SM_AO ) {
      loader = new ObjLoader( m_filename.c_str(), m_context, m_geometry_group, m_material );
    } else if ( m_shade_mode == SM_ONE_BOUNCE_DIFFUSE ) {
      loader = new ObjLoader( m_filename.c_str(), m_context, m_geometry_group, m_material, true );
    } else {
      loader = new ObjLoader( m_filename.c_str(), m_context, m_geometry_group );
    }

    const std::string geom_ptx = ptxpath( "displacement", "geometry_programs.cu" );
    loader->setIntersectProgram(m_context->createProgramFromPTXFile( geom_ptx, "mesh_intersect" ) );
    loader->setBboxProgram(m_context->createProgramFromPTXFile( geom_ptx, "mesh_bounds" ) );

    loader->load();
    m_aabb = loader->getSceneBBox();
    delete loader;

  } else if( PlyLoader::isMyFile( m_filename ) ) {
    // Load PLY model 
    PlyLoader loader( m_filename, m_context, m_geometry_group, m_material );
    loader.load();

    m_aabb = loader.getSceneBBox();

  } else {
    std::cerr << "Unrecognized model file extension '" << m_filename << "'" << std::endl;
    exit( 0 );
  }

  // Override acceleration structure builder. The default used by the ObjLoader is Sbvh.
  if( !m_accel_builder.empty() ) {
    Acceleration accel = m_geometry_group->getAcceleration();
    accel->setBuilder( m_accel_builder );
  }

  Acceleration accel = m_geometry_group->getAcceleration();
  accel->setBuilder("Bvh");

  // Override traverer if one is given.
  if( !m_accel_traverser.empty() ) {
    Acceleration accel = m_geometry_group->getAcceleration();
    accel->setTraverser( m_accel_traverser );
  }

  if( m_accel_builder == "TriangleKdTree" || m_accel_traverser == "KdTree") {
    Acceleration accel = m_geometry_group->getAcceleration();
    accel->setProperty( "vertex_buffer_name", "vertex_buffer" );
    accel->setProperty( "index_buffer_name", "vindex_buffer" );
  }
  
  // Load acceleration structure from a file if that was enabled on the
  // command line, and if we can find a cache file. Note that the type of
  // acceleration used will be overridden by what is found in the file.
  loadAccelCache();

  
  m_context[ "top_object" ]->set( m_geometry_group );
  m_context[ "top_shadower" ]->set( m_geometry_group );

}