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 }