예제 #1
0
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);
    }
}
예제 #2
0
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

}