bool Face::triangle_intersect(const Ray &r, Hit &h, Vertex *a, Vertex *b, Vertex *c, bool intersect_backfacing) const {

  // compute the intersection with the plane of the triangle
  Hit h2 = Hit(h);
  if (!plane_intersect(r,h2,intersect_backfacing)) return 0;  

  // figure out the barycentric coordinates:
  glm::vec3 Ro = r.getOrigin();
  glm::vec3 Rd = r.getDirection();
  // [ ax-bx   ax-cx  Rdx ][ beta  ]     [ ax-Rox ] 
  // [ ay-by   ay-cy  Rdy ][ gamma ]  =  [ ay-Roy ] 
  // [ az-bz   az-cz  Rdz ][ t     ]     [ az-Roz ] 
  // solve for beta, gamma, & t using Cramer's rule
  
  glm::mat3 detA_mat(a->get().x-b->get().x,a->get().x-c->get().x,Rd.x,
                     a->get().y-b->get().y,a->get().y-c->get().y,Rd.y,
                     a->get().z-b->get().z,a->get().z-c->get().z,Rd.z);
  float detA = glm::determinant(detA_mat);

  if (fabs(detA) <= 0.000001) return 0;
  assert (fabs(detA) >= 0.000001);
  
  glm::mat3 beta_mat(a->get().x-Ro.x,a->get().x-c->get().x,Rd.x,
                     a->get().y-Ro.y,a->get().y-c->get().y,Rd.y,
                     a->get().z-Ro.z,a->get().z-c->get().z,Rd.z);
  
  glm::mat3 gamma_mat(a->get().x-b->get().x,a->get().x-Ro.x,Rd.x,
                      a->get().y-b->get().y,a->get().y-Ro.y,Rd.y,
                      a->get().z-b->get().z,a->get().z-Ro.z,Rd.z);

  float beta = glm::determinant(beta_mat) / detA;
  float gamma = glm::determinant(gamma_mat) / detA;

  if (beta >= -0.00001 && beta <= 1.00001 &&
      gamma >= -0.00001 && gamma <= 1.00001 &&
      beta + gamma <= 1.00001) {
    h = h2;
    // interpolate the texture coordinates
    float alpha = 1 - beta - gamma;
    float t_s = alpha * a->get_s() + beta * b->get_s() + gamma * c->get_s();
    float t_t = alpha * a->get_t() + beta * b->get_t() + gamma * c->get_t();
    h.setTextureCoords(t_s,t_t);
    assert (h.getT() >= EPSILON);
    return 1;
  }

  return 0;
}
示例#2
0
bool Face::triangle_intersect(const Ray &r, Hit &h, Vertex *a, Vertex *b, Vertex *c, bool intersect_backfacing, bool* backfacing_hit) {

	*backfacing_hit = false;
	// compute the intersection with the plane of the triangle
	Hit h2 = Hit(h);
	if (!plane_intersect(r,h2,intersect_backfacing, backfacing_hit)) return 0;	

	// figure out the barycentric coordinates:
	Vec3f Ro = r.getOrigin();
	Vec3f Rd = r.getDirection();
	// [ ax-bx	 ax-cx	Rdx ][ beta	]		 [ ax-Rox ] 
	// [ ay-by	 ay-cy	Rdy ][ gamma ]	=	[ ay-Roy ] 
	// [ az-bz	 az-cz	Rdz ][ t		 ]		 [ az-Roz ] 
	// solve for beta, gamma, & t using Cramer's rule
	
	double detA = Matrix::det3x3(a->get().x()-b->get().x(),a->get().x()-c->get().x(),Rd.x(),
						 a->get().y()-b->get().y(),a->get().y()-c->get().y(),Rd.y(),
						 a->get().z()-b->get().z(),a->get().z()-c->get().z(),Rd.z());
	
	if (fabs(detA) <= 0.000001) return 0;
	assert (fabs(detA) >= 0.000001);

	double beta	= Matrix::det3x3(a->get().x()-Ro.x(),a->get().x()-c->get().x(),Rd.x(),
				a->get().y()-Ro.y(),a->get().y()-c->get().y(),Rd.y(),
				a->get().z()-Ro.z(),a->get().z()-c->get().z(),Rd.z()) / detA;
	
	double gamma = Matrix::det3x3(a->get().x()-b->get().x(),a->get().x()-Ro.x(),Rd.x(),
				a->get().y()-b->get().y(),a->get().y()-Ro.y(),Rd.y(),
				a->get().z()-b->get().z(),a->get().z()-Ro.z(),Rd.z()) / detA;

	//Case of an intersection
	if (beta >= -0.00001 && beta <= 1.00001 &&
			gamma >= -0.00001 && gamma <= 1.00001 &&
			beta + gamma <= 1.00001) {
		h = h2;
		// interpolate the texture coordinates
		double alpha = 1 - beta - gamma;
		double t_s = alpha * a->get_s() + beta * b->get_s() + gamma * c->get_s();
		double t_t = alpha * a->get_t() + beta * b->get_t() + gamma * c->get_t();
		h.setTextureCoords(t_s,t_t);
		assert (h.getT() >= EPSILON);
		return 1;
	}

	return 0;
}