Beispiel #1
0
void ObjLoader::loadVertexData( GLMmodel* model, const optix::Matrix4x4& transform )
{
  unsigned int num_vertices  = model->numvertices;
  unsigned int num_texcoords = model->numtexcoords;
  unsigned int num_normals   = model->numnormals;

  // Create vertex buffer
  _vbuffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT3, num_vertices );
  float3* vbuffer_data = static_cast<float3*>( _vbuffer->map() );

  // Create normal buffer
  _nbuffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT3, num_normals );
  float3* nbuffer_data = static_cast<float3*>( _nbuffer->map() );

  // Create texcoord buffer
  _tbuffer = _context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT2, num_texcoords );
  float2* tbuffer_data = static_cast<float2*>( _tbuffer->map() );

  // Transform and copy vertices.  
  for ( unsigned int i = 0; i < num_vertices; ++i )
  {
    const float3 v3 = *((float3*)&model->vertices[(i+1)*3]);
    float4 v4 = make_float4( v3, 1.0f );
    vbuffer_data[i] = make_float3( transform*v4 );
  }

  // Transform and copy normals.
  const optix::Matrix4x4 norm_transform = transform.inverse().transpose();
  for( unsigned int i = 0; i < num_normals; ++i )
  {
    const float3 v3 = *((float3*)&model->normals[(i+1)*3]);
    float4 v4 = make_float4( v3, 0.0f );
    nbuffer_data[i] = make_float3( norm_transform*v4 );
  }

  // Copy texture coordinates.
  memcpy( static_cast<void*>( tbuffer_data ),
          static_cast<void*>( &(model->texcoords[2]) ),
          sizeof( float )*num_texcoords*2 );   

  // Calculate bbox of model
  for( unsigned int i = 0; i < num_vertices; ++i )
    _aabb.include( vbuffer_data[i] );

  // Unmap buffers.
  _vbuffer->unmap();
  _nbuffer->unmap();
  _tbuffer->unmap();
}
void sample_instance(
    const bake::Mesh& mesh,
    const optix::Matrix4x4& xform,
    const unsigned int seed,
    const size_t min_samples_per_triangle,
    bake::AOSamples&  ao_samples
    )
{

  // Setup access to mesh data
  const optix::Matrix4x4 xform_invtrans = xform.inverse().transpose();
  assert( ao_samples.num_samples >= mesh.num_triangles*min_samples_per_triangle );
  assert( mesh.vertices               );
  assert( mesh.num_vertices           );
  assert( ao_samples.sample_positions );
  assert( ao_samples.sample_normals   );
  assert( ao_samples.sample_infos     );

  const int3*   tri_vertex_indices  = reinterpret_cast<int3*>( mesh.tri_vertex_indices );
  float3* sample_positions  = reinterpret_cast<float3*>( ao_samples.sample_positions );   
  float3* sample_norms      = reinterpret_cast<float3*>( ao_samples.sample_normals   );   
  float3* sample_face_norms = reinterpret_cast<float3*>( ao_samples.sample_face_normals );
  bake::SampleInfo* sample_infos = ao_samples.sample_infos;

  const unsigned vertex_stride_bytes = mesh.vertex_stride_bytes > 0 ? mesh.vertex_stride_bytes : 3*sizeof(float);
  const unsigned normal_stride_bytes = mesh.normal_stride_bytes > 0 ? mesh.normal_stride_bytes : 3*sizeof(float);

  // Compute triangle areas
  std::vector<double> tri_areas(mesh.num_triangles, 0.0);
  for ( size_t tri_idx = 0; tri_idx < mesh.num_triangles; tri_idx++ ) {
    const int3& tri = tri_vertex_indices[tri_idx];
    const float3* verts[] = {get_vertex(mesh.vertices, vertex_stride_bytes, tri.x),
                             get_vertex(mesh.vertices, vertex_stride_bytes, tri.y),
                             get_vertex(mesh.vertices, vertex_stride_bytes, tri.z)};
    const double area = triangle_area(xform*verts[0][0], xform*verts[1][0], xform*verts[2][0]);
    tri_areas[tri_idx] = area;
  }

  // Get sample counts
  std::vector<size_t> tri_sample_counts(mesh.num_triangles, 0);
  TriangleSamplerCallback cb((unsigned)min_samples_per_triangle, &tri_areas[0]);
  distribute_samples_generic(cb, ao_samples.num_samples, mesh.num_triangles, &tri_sample_counts[0]);

  // Place samples
  size_t sample_idx = 0;
  for (size_t tri_idx = 0; tri_idx < mesh.num_triangles; tri_idx++) {
    const int3& tri = tri_vertex_indices[tri_idx];
    const float3* verts[] = {get_vertex(mesh.vertices, vertex_stride_bytes, tri.x),
                             get_vertex(mesh.vertices, vertex_stride_bytes, tri.y),
                             get_vertex(mesh.vertices, vertex_stride_bytes, tri.z)};
    const float3** normals = NULL;
    const float3* norms[3];
    if (mesh.normals) {
      norms[0] = get_vertex(mesh.normals, normal_stride_bytes, tri.x);
      norms[1] = get_vertex(mesh.normals, normal_stride_bytes, tri.y);
      norms[2] = get_vertex(mesh.normals, normal_stride_bytes, tri.z);
      normals = norms;
    }
    sample_triangle(xform, xform_invtrans, verts, normals, 
      tri_idx, tri_sample_counts[tri_idx], tri_areas[tri_idx],
      seed,
      sample_positions+sample_idx, sample_norms+sample_idx, sample_face_norms+sample_idx, sample_infos+sample_idx);
    sample_idx += tri_sample_counts[tri_idx];
  }

  assert( sample_idx == ao_samples.num_samples );

#ifdef DEBUG_MESH_SAMPLES
  for (size_t i = 0; i < ao_samples.num_samples; ++i ) {
    const SampleInfo& info = sample_infos[i];
    std::cerr << "sample info (" << i << "): " << info.tri_idx << ", (" << info.bary[0] << ", " << info.bary[1] << ", " << info.bary[2] << "), " << info.dA << std::endl;
  }
#endif

}