void Radiosity::ComputeFormFactors() { assert (formfactors == NULL); assert (num_faces > 0); formfactors = new double[num_faces*num_faces]; // ===================================== // ASSIGNMENT: COMPUTE THE FORM FACTORS // ===================================== for (int i = 0; i < num_faces; ++i) { for (int j = i; j < num_faces; ++j) { if (i == j) { formfactors[i * num_faces + j] = 0; continue; } Face *f1 = mesh->getFace(i); Face *f2 = mesh->getFace(j); double formfactor = 0.0; Vec3f p1 = f1->computeCentroid(); Vec3f p2 = f2->computeCentroid(); // Get the vec for p1-->p2 Vec3f line_p1p2 = p2 - p1; double R2 = line_p1p2.Length() * line_p1p2.Length(); Vec3f p1Normal = f1->computeNormal(); line_p1p2.Normalize(); double cos_p1 = p1Normal.Dot3(line_p1p2); Vec3f p2Normal = f2->computeNormal(); double cos_p2 = p2Normal.Dot3(-line_p1p2); double ff = 0.0; if (cos_p1 > EPSILON && cos_p2 > EPSILON) { ff = cos_p1 * cos_p2 / (M_PI * R2); } formfactor += ff; formfactors[i * num_faces + j] = formfactor * getArea(i)/getArea(j); formfactors[j * num_faces + i] = formfactor * getArea(j)/getArea(i); } normalizeFormFactors(i); } }
void Radiosity::ComputeFormFactors() { assert (formfactors == NULL); assert (num_faces > 0); formfactors = new float[num_faces*num_faces]; // ===================================== // ASSIGNMENT: COMPUTE THE FORM FACTORS // ===================================== //cycle through every pair for (int i=0; i<num_faces; i++){ for (int j=0; j<num_faces; j++){ //a surface does not distribute any light to itself float form_factor=0.0; if (i==j){ formfactors[i*num_faces+j]=0.0; } //check for occlusions... //here we actually have to calculate the form factor... else{ for (int samples=0; samples<args->num_form_factor_samples; samples++){ float phi_i, phi_j, Aj, r; glm::vec3 disp; Face* face_i=mesh->getFace(i); Face* face_j=mesh->getFace(j); glm::vec3 norm_i= glm::normalize(face_i->computeNormal()); glm::vec3 norm_j= glm::normalize(face_j->computeNormal()); //first compute the displacement vector between the two faces. //points from i to j //use below code when you want to trace from center to center //disp = face_i->computeCentroid()-face_j->computeCentroid(); glm::vec3 face_j_point=face_j->RandomPoint(); disp = face_i->RandomPoint()-face_j_point; Hit h; r = glm::length(disp); //if we are only taking one sample we want it from the center for consistency if (args->num_form_factor_samples==1){ disp=face_i->computeCentroid()-face_j->computeCentroid(); r = glm::length(disp); face_j_point=face_j->computeCentroid(); } Ray ray(face_j_point, glm::normalize(disp)); raytracer->CastRay(ray, h, true); //here we test for occlusion if ( args->num_shadow_samples>0 and !(h.getT()>r-0.001 and h.getT()<r+0.001) ){ //setFormFactor(i,j, 0.0); } else{ //std::cout<<"r is "<<r<<std::endl; disp = -glm::normalize(disp); //compute the rest of the constants phi_i = fabs(glm::dot(norm_i, disp)); //std::cout<<"phi_i is "<<phi_i<<std::endl; disp = -disp; phi_j = fabs(glm::dot(norm_j, disp)); //std::cout<<"phi_j is "<<phi_j<<std::endl; Aj = face_j->getArea(); //std::cout<<"Aj is "<<Aj<<std::endl; //compute and enter the form factor //setFormFactor(i,j,(phi_i)*(phi_j)*Aj/(3.14159265359*r*r)); form_factor+=(phi_i)*(phi_j)*Aj/(3.14159265359*r*r); // formfactors[i*num_faces+j]=10000000000000000.0*glm::cos(phi_i)*glm::cos(phi_j)*Aj/(3.14159265359*r*r); } } } setFormFactor(i,j,form_factor/(float(args->num_form_factor_samples))); } normalizeFormFactors(i); } #if 0 std::cout<<"formfactors matrix is\n"; for (int i=0; i<num_faces; i++){ for(int j=0; j<num_faces;j++){ std::cout<<formfactors[i*num_faces+j]<<' '; } std::cout<<'\n'; } #endif }