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] ); }
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 ); }