inline bool Triangle::intersect(Ray& ray, Intersection& intersection) { vec3 pvec = cross(ray.direction, edge2); float det = dot(edge1, pvec); if(det <= 0.0) return false; vec3 tvec = ray.origin - vert0; float u = dot(tvec, pvec); if(u < 0.0f || u > det) return false; vec3 qvec = cross(tvec, edge1); float v = dot(ray.direction, qvec); if(v < 0.0f || u + v > det) return false; float t = dot(edge2, qvec); float inv_det = 1.0f / det; t *= inv_det; //u *= inv_det; //v *= inv_det; if(t >= intersection.getT()) return false; intersection.set(t, ray.getPosition(t), cross(edge1, edge2), edge1, this); return true; }
Colour* rayTrace(const Colour& ambient, const Point3D& eye, Ray ray, SceneNode* root, const std::list<Light*>& lights, int level, double fogDist){ if(level <= 0) return NULL; Intersection* i = root->intersect(ray); bool fogOn = true; if(fogDist <= 0) fogOn = false; if(i != NULL){ Colour color(0,0,0); Colour fog(0.8,0.8,0.8); Colour diffuse(0,0,0), specular(0,0,0); Material* material = i->getMaterial(); Vector3D n = i->getNormal(); n.normalize(); Point3D p = i->getPoint(); Vector3D v = eye - p; v.normalize(); for (std::list<Light*>::const_iterator I = lights.begin(); I != lights.end(); ++I) { Light light = **I; Vector3D l = light.position - p; l.normalize(); Vector3D r = 2*l*n*n - l; r.normalize(); // shadows Ray lightRay = Ray(p, l); Intersection* lightIsc = root->intersect(lightRay); if(lightIsc == NULL){ // add light contribution //std::cerr << "light" << std::endl; if(n*l > 0) diffuse = diffuse + material->getDiffuse() * (l*n) * light.colour; if(r*v > 0) specular = specular + material->getSpecular() * pow((r*v), material->getShininess()) * light.colour; } } //secondaty rays Vector3D r = 2*v*n*n - v; r.normalize(); Ray refRay(p, r); Colour* reflectedColor = rayTrace(ambient, eye, refRay, root, lights, level-1, fogDist); if(reflectedColor != NULL){ if(n*r > 0) diffuse = diffuse + material->getDiffuse() * (r*n) * material->getReflectivity() * (*reflectedColor); if(r*v > 0) specular = specular + material->getSpecular() * pow((r*v), material->getShininess()) * material->getReflectivity() * (*reflectedColor); } color = ambient*material->getColor() + diffuse + specular; if(fogOn){ double dist = i->getT()/fogDist; if(dist>1) dist=1; color = (1-dist)*color + dist*fog; } return new Colour(color); } return NULL; }