//intersect sphere with a ray bool Sphere::intersect(const Ray &ray, IntersectionData* iData) { //=== EXERCISE 1.3.2 === //Resolving the problem algebraicaly, we get the following coefficients of a quadratic equation in t: double a=ray.direction.dot(ray.direction); double b=2*(ray.point.dot(ray.direction) - m_center.dot(ray.direction)); double c=m_center.dot(m_center)+ray.point.dot(ray.point) - 2.0*m_center.dot(ray.point) - m_radius*m_radius; double discriminant = b*b - 4.0*a*c; if (discriminant<0) { return false; }else{ double t1=(-b+sqrt(discriminant))/(2.0*a); double t2=(-b-sqrt(discriminant))/(2.0*a); bool b1= (t1>=ray.min_t && t1<=ray.max_t) && t1<iData->t ; bool b2= (t2>=ray.min_t && t2<=ray.max_t) && t2<iData->t ; if (b1||b2) { if(b1) iData->t=t1; if(b2) iData->t=t2; if (b1 && b2) { iData->t=(t2<t1?t2:t1); } iData->position=ray.getPointOnRay(iData->t); iData->color=getColor(); iData->material=getMaterial(); iData->sourcePosition=ray.point; iData->normal=(ray.getPointOnRay(iData->t) - m_center).normalize(); iData->reflectionPercentage=getReflectionPercentage(); iData->refractionIndex=getRefractionIndex(); iData->refractionPercentage=getRefractionPercentage(); iData->rayEntersObject= (ray.direction.dot(iData->normal)<0.0); iData->reflectionPercentage = getReflectionPercentage(); return true; } } return false; }
//intersect triangle with a ray bool Triangle::intersect(const Ray &ray, IntersectionData* iData) { //=== EXERCISE 1.4.2 === Vector3 n = (m_p3 - m_p1).cross(m_p2 - m_p1); if (ray.direction.dot(n) == 0) { // no solution return false; }else{ // compute the solution double t = - ((ray.point - m_p1).dot(n))/(ray.direction.dot(n)); // check if solution is valid for our problem bool b = (t>=ray.min_t && t<=ray.max_t) && t<iData->t; if(b){ // normal vector of small triangles Vector3 x = ray.getPointOnRay(t); Vector3 n_s1 = (m_p2 - m_p3).cross(x - m_p3); Vector3 n_s2 = (m_p1 - m_p2).cross(x - m_p2); Vector3 n_s3 = (m_p3 - m_p1).cross(x - m_p1); // compute s1 s2 s3 (normalise) double s1 = (n.dot(n_s1))/(n.x*n.x + n.y*n.y + n.z*n.z); double s2 = (n.dot(n_s2))/(n.x*n.x + n.y*n.y + n.z*n.z); double s3 = (n.dot(n_s3))/(n.x*n.x + n.y*n.y + n.z*n.z); // test if p is in triangle if(1-ray.epsilon_t < s1+s2+s3 && s1+s2+s3 < 1+ray.epsilon_t && 0 < s1 && s1<1 && 0<s2 && s2<1 && 0<s3 && s3<1){ iData->t=t; //Intersection information iData->position=ray.getPointOnRay(iData->t); iData->color=getColor(); iData->sourcePosition=ray.point; return true; }else{ return false; } }else{ return false; } } return false; }
//intersect triangle with a ray bool Triangle::intersect(const Ray &ray, IntersectionData* iData) { //=== EXERCISE 1.4.2 === Vector3 n = (m_p3 - m_p1).cross(m_p2 - m_p1); if (ray.direction.dot(n) == 0) { // no solution return false; }else{ // compute the solution double t = - ((ray.point - m_p1).dot(n))/(ray.direction.dot(n)); // check if solution is valid for our problem bool b = (t>=ray.min_t && t<=ray.max_t) && t<iData->t; if(b){ // normal vector of small triangles Vector3 x = ray.getPointOnRay(t); Vector3 n_s1 = (m_p2 - m_p3).cross(x - m_p3); Vector3 n_s2 = (m_p1 - m_p2).cross(x - m_p2); Vector3 n_s3 = (m_p3 - m_p1).cross(x - m_p1); // compute s1 s2 s3 (normalise) double s1 = (n.dot(n_s1))/(n.x*n.x + n.y*n.y + n.z*n.z); double s2 = (n.dot(n_s2))/(n.x*n.x + n.y*n.y + n.z*n.z); double s3 = (n.dot(n_s3))/(n.x*n.x + n.y*n.y + n.z*n.z); // test if p is in triangle if(1-ray.epsilon_t < s1+s2+s3 && s1+s2+s3 < 1+ray.epsilon_t && 0 < s1 && s1<1 && 0<s2 && s2<1 && 0<s3 && s3<1){ iData->t=t; //Intersection information iData->position=ray.getPointOnRay(iData->t); iData->color=getColor(); iData->sourcePosition=ray.point; iData->reflectionPercentage = getReflectionPercentage(); // Exercice 2.1.1 iData->material = getMaterial(); //Normal interpolation Vector3 normal1 = m_n1.operator*(s1); Vector3 normal2 = m_n2.operator*(s3); Vector3 normal3 = m_n3.operator*(s2); // s2 and s3 are inverted du to the typing error on the triangle in slide Vector3 normal = (normal1+normal2+normal3).normalize(); // get the interpolated normal in x iData->normal = normal; return true; }else{ return false; } }else{ return false; } } return false; }