TriMesh* Scene::load_background_mesh(const string& filename, const Mat4x4f& transform) { TriMesh* mesh = new TriMesh; obj_load(filename, *mesh); if(!mesh->has_normals()) { cout << "Computing normals" << endl; mesh->compute_normals(); } mesh->transform(transform); mesh->compute_areas(); cout << "No. of triangles: " << mesh->geometry.no_faces() << endl; meshes.push_back(mesh); return mesh; }
unsigned int Scene::extract_area_lights(RayTracer* tracer, unsigned int samples_per_light) { light_tracer = tracer; for(unsigned int i = 0; i < meshes.size(); ++i) { TriMesh* mesh = new TriMesh; const vector<int>& indices = meshes[i]->mat_idx; for(unsigned int j = 0; j < indices.size(); ++j) { const ObjMaterial& mat = meshes[i]->materials[indices[j]]; if(mat.name == "default") continue; bool emissive = false; for(unsigned int k = 0; k < 3; ++k) emissive = emissive || (meshes[i]->materials[indices[j]].ambient[k] > 0.0f); if(emissive) { Vec3i g_face = meshes[i]->geometry.face(j); for(unsigned int k = 0; k < 3; ++k) g_face[k] = mesh->geometry.add_vertex(meshes[i]->geometry.vertex(g_face[k])); int idx = mesh->geometry.add_face(g_face); if(meshes[i]->normals.no_faces() > j) { Vec3i n_face = meshes[i]->normals.face(j); for(unsigned int k = 0; k < 3; ++k) n_face[k] = mesh->normals.add_vertex(meshes[i]->normals.vertex(n_face[k])); mesh->normals.add_face(n_face, idx); } if(meshes[i]->texcoords.no_faces() > j) { Vec3i t_face = meshes[i]->texcoords.face(j); for(unsigned int k = 0; k < 3; ++k) t_face[k] = mesh->texcoords.add_vertex(meshes[i]->texcoords.vertex(t_face[k])); mesh->texcoords.add_face(t_face, idx); } bool material_exists = false; for(unsigned int k = 0; k < mesh->materials.size(); ++k) if(mesh->materials[k].name == meshes[i]->materials[indices[j]].name) { mesh->mat_idx.push_back(k); material_exists = true; break; } if(!material_exists) { mesh->mat_idx.push_back(mesh->materials.size()); mesh->materials.push_back(meshes[i]->materials[indices[j]]); } } } if(mesh->geometry.no_faces() == 0) delete mesh; else { mesh->compute_areas(); light_meshes.push_back(mesh); extracted_lights.push_back(lights.size()); lights.push_back(new AreaLight(light_tracer, mesh, samples_per_light)); } } return lights.size(); }