Example #1
0
TEST(IntersectTest, IntersectValueTest) {

    Sphere sphere = Sphere(vec3(1,0,0), 1);

    float *thit = new float(0);
    LocalGeo *local = new LocalGeo(Point(vec4(0,0,0,1)), Normal(vec3(0,0,0)));

    // 2 real positive roots, pick smaller one
    Ray ray1 = Ray(vec3(-1,0,0), vec3(1,0,0), 0, 0, 100);
    sphere.intersect(ray1, thit, local);
    EXPECT_EQ(*thit, 1);
    EXPECT_EQ(local->point.p, vec4(0,0,0,1));
    EXPECT_EQ(local->normal.p, vec3(-1,0,0));

    // tangent
    Ray ray2 = Ray(vec3(0,0,0), vec3(0,1,0), 0, 0, 100);
    EXPECT_EQ(sphere.intersect(ray2, thit, local), true);
    EXPECT_EQ(*thit, 0);
    EXPECT_EQ(local->point.p, vec4(0,0,0,1));
    EXPECT_EQ(local->normal.p, vec3(-1,0,0));

    // one positive, one negative
    Ray ray3 = Ray(vec3(1,0,0), vec3(1,0,0), 0, 0, 100);
    EXPECT_EQ(sphere.intersect(ray3, thit, local), true);
    EXPECT_EQ(*thit, 1);
    EXPECT_EQ(local->point.p, vec4(2,0,0,1));
    EXPECT_EQ(local->normal.p, vec3(1,0,0));

    // no intersection
    Ray ray4 = Ray(vec3(-1,0,0), vec3(0,1,0), 0, 0, 100);
    EXPECT_EQ(sphere.intersect(ray4, thit, local), false);



}
Example #2
0
 double intersect(Ray& r, Vector& normal){
     if(boundVol.intersect(r, normal)<0) return -1;
     double t=1e30;
     Vector norm;
     bool found=false;
     int in=-1;
     for(int i=0;i<98;i++){
         double t2=triangles[i].intersect(r, norm);
         if(t2<t&&t2>EPS){
             found=true;
             t=t2;
             in=i;
         }
     }
     if(found){
         Vector a=triangles[in].p3-triangles[in].p1;
         Vector b=triangles[in].p2-triangles[in].p1;
         Vector c=r[t]-triangles[in].p1;
         double aa=a*a;
         double ab=a*b;
         double ac=a*c;
         double bb=b*b;
         double bc=b*c;
         double det=1/(aa*bb-ab*ab);
         double u=(bb*ac-ab*bc)*det;
         double v=(aa*bc-ab*ac)*det;
         normal=triangles[in].n1*(1-u-v)+triangles[in].n2*(v)+triangles[in].n3*(u);
         return t;
     }
     return -1;
 }
Example #3
0
static void IsectRaySphere(benchmark::State& state) {
    RayIntersection isect;
    Ray ray(Vector4(0, 0, -10), Vector4(0, 0, 1));
    Sphere obj;
    float hit;
    for (auto _ : state) {
        hit = obj.intersect(ray, isect);
        benchmark::DoNotOptimize(hit);
    }
}
Example #4
0
TEST(SphereTest, TranslateIntersectNormalTest) {
    Sphere sphere = Sphere(vec3(2,0,0), 1);
    sphere.set_transform(mat4(1,0,0,0,
                              0,1,0,0,
                              0,0,1,0,
                              -1,0,0,1)); //center now at (1,0,0)

    Ray ray = Ray(vec3(0,0,2), vec3(0,0,-1), 0, 0, 100);
    EXPECT_EQ(sphere.intersectP(ray), true);

    LocalGeo *local = new LocalGeo(Point(), Normal());
    float *t = new float(0);

    sphere.intersect(ray, t, local);
    EXPECT_EQ(local->normal.p, vec3(-1,0,0));
}
Example #5
0
 Color trace(Ray * ray, vector<Sphere>  balls, int depth){

	 if (depth == 0){
		 return Color(0.0f, 0.0f, 0.0f);
	 }

	 float closest_t = 999999999999999999; //FIX ME MAX FLOAT
	 Sphere * closest_sphere = 0; 
	 bool hit = false;
	 int id = 0; 
	 for (int x = 0; x < balls.size(); x++){
		 Sphere  sphere = ((balls)[x]);
		 if (sphere.hit(ray) == 1){
			 hit = true;
			 float intersect = sphere.intersect(ray);
			 if (intersect < closest_t){
				 closest_t = intersect;
				 closest_sphere = &((balls)[x]);
				 id = x; 
			 }
		}
	}

	 Color rgb(0.0f, 0.0f, 0.0f);


	 if (hit){	
		 //return closest_sphere->diffuse(ray, closest_t) + closest_sphere->specular(ray, closest_t)+trace(;
		 /*
		 for (int a = 0.0f; a < alights.size(); a++){
			 rgb.red += .3f*alights[a].red;
			 rgb.green += .15*alights[a].green;
			 rgb.blue += 0.0f*alights[a].blue;
		 }
		 */

		 for (int a = 0.0f; a < plights.size(); a++){
			 rgb.red += .3f*plights[a].red;
			 rgb.green += .15*plights[a].green;
			 rgb.blue += 0.0f*plights[a].blue;
		 }

		 rgb= rgb + closest_sphere->diffspec(ray, closest_t, id);
	 }
	 return rgb;;
 }
Example #6
0
void renderNormal(Sphere scene, PerspectiveCamera camera)
{
	for(int y=0;y<Y_RES;y++)
	{
		float sy =  (float)y/Y_RES;
		for(int x=0;x<X_RES;x++)
		{
			float sx = (float)x/X_RES;
			Ray3 ray = camera.generateRay(sx,sy);
			IntersectResult result = scene.intersect(ray);
			if(result.getGeometry())
			{

				fbuffer[y][x][0]=(result.getNormal().getx()+1)*128;
				fbuffer[y][x][1]=(result.getNormal().gety()+1)*128;
				fbuffer[y][x][2]=(result.getNormal().getz()+1)*128;
			}
		}
	}
}
Example #7
0
void rayTrace2( Sphere scene, PerspectiveCamera camera)
{
	for(int y=0;y<Y_RES;y++)
	{
		float sy =  (float)y/Y_RES;
		for(int x=0;x<X_RES;x++)
		{
			float sx = (float)x/X_RES;
			Ray3 ray = camera.generateRay(sx,sy);
			IntersectResult result = scene.intersect(ray);
			if(result.getGeometry())
			{
				cout<<"x:"<<y<<" y:"<<x<<endl;
				Color color = PhongMaterial(Color::red,Color::white,16,1).sample(ray, result.getPosition(), result.getNormal());
				fbuffer[y][x][0]=color.getR()*255;
				fbuffer[y][x][1]=color.getG()*255;
				fbuffer[y][x][2]=color.getB()*255;
			}
		}
	}

}
Example #8
0
void renderDepth(Sphere scene, PerspectiveCamera camera, int maxDepth)
{
	for(int y=0;y<Y_RES;y++)
	{
		float sy =  (float)y/Y_RES;
		for(int x=0;x<X_RES;x++)
		{
			float sx = (float)x/X_RES;
			Ray3 ray = camera.generateRay(sx,sy);
			IntersectResult result = scene.intersect(ray);
			if(result.getGeometry())
			{
				int depth = 255 - Min((result.getDistance()/maxDepth)*255,255);
				
				//cout<< "x: " << x << " y: " << y << " depth: "<<depth<<" dis: "<<result.getDistance()<<endl;

				fbuffer[y][x][0]=depth;
				fbuffer[y][x][1]=depth;
				fbuffer[y][x][2]=depth;
			}
		}
	}
}
Example #9
0
/** Phong lighting model
 ** @param pt intersection point
 ** @param n normal of pt
 ** @param light pointer to the light source
 ** @param obj pointer to the object
 ** @param ray ray
 ** @return color calculated from local shading using phong model
 **/
Vec phongModel(Vec pt, Vec n, Light* light, Shape* obj, Ray ray) {
  float t;
  Vec v = ray.getOrig() - pt; v = v.normalize(); // vector to viewer
  Vec l = light->pos - pt;
  float dis = l.mag(); // distance to light source
  l = l.normalize(); // vector to light source
  Vec ir = n * (2 * n.dot(l)) - l; ir = ir.normalize(); // vector of ideal reflector
  Vec intensity = light->intensity; // light intensity
  Ray shadowRay(pt, l, 0, 9999, ShadowRay);  // shadow ray to the light source
  float f = light->attenFac(dis); // attentuation factor
  Pigment p = obj->getPigment();
  Vec obj_color; // object color
  float scalar; int tmp;
  if (p.type == SOLID) {
    obj_color = p.c1;
  } else if (p.type == CHECKER) {
    scalar = p.width;
    tmp = (int)(pt.x/scalar) + (int)(pt.y/scalar) + (int)(pt.z/scalar);
    if (tmp % 2 == 0) obj_color = p.c1;
    else obj_color = p.c2;
  } else if (p.type == TEXTURE) {
    if (obj->getType() == sphere)
      obj_color = sphereMapping(pt, n, p);
  }
  
  // get the surface parameters
  SurFinish appearance = obj->getSurFin();
  float Ka = appearance.ambient; // ambient coefficient
  float Kd = appearance.diffuse; // diffuse coefficient
  float Ks = appearance.specular; // specular coefficient
  float shininess = appearance.shininess;
  
  // for each object in the scene, see if is blocks the light
  if (light->type != ambient) {
    for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) {
      if ((*its) == obj) continue;
      
      if ((*its)->getType() == sphere) {
        Sphere *shape = dynamic_cast<Sphere*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis)
          return black;
      } else if((*its)->getType() == polyhedron){
        Polyhedron *shape = dynamic_cast<Polyhedron*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis) {
          return black;
        }
      } else if((*its)->getType() == triangleMesh){
        TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its);
        if (shape->intersect(shadowRay, t) && shadowRay.calcDest(t).mag() < dis)
          return black;
      }
    }
  }
  
  Vec diffuse(0.0, 0.0, 0.0);
  Vec specular(0.0, 0.0, 0.0);
  // if the light is casted from front
  if (n.dot(l) > 0) {
    diffuse = intensity * (Kd * n.dot(l) * f);
    specular = white * (Ks * pow(v.dot(ir),shininess) * f);
    // update light color
    intensity.x = (light->type != ambient) ? diffuse.x * obj_color.x + specular.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? diffuse.y * obj_color.y + specular.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? diffuse.z * obj_color.z + specular.z : obj_color.z * Ka;
  } // if the light is casted from behind
  else {
    intensity.x = (light->type != ambient) ? black.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? black.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? black.z : obj_color.z * Ka;
  }
  
  return intensity;
}
Example #10
0
/** Ray Tracer
 ** @param ray the ray to be traced
 ** @param depth recursion depth
 ** @return color value
 **/
Vec trace(Ray ray, int depth){
  if (debugMode) {
    printf("\nrecursion = %d\n", depth);
    printf("ray origin = "); ray.getOrig().print();
    printf("ray direction = "); ray.getDir().print();
  }
  if (depth == 0) return black; // return background color
  
  Vec color, local, reflected, transmitted;
  Vec pt, normal;
  float tClosest = ray.getTmax(); // set dis to a maximum value
  Shape *ObjPtr = NULL; // set the Obj pointer to null
  
  // look for intersection point for each object in the scene
  bool inside = false;
  for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) {
    if ((*its) == ray.ObjPtr) continue;
    float t;
    
    if ((*its)->getType() == sphere) {
      Sphere *shape = dynamic_cast<Sphere*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          inside = (shape->intersect(ray, t) == -1) ? true : false;
          tClosest = t; // update tClosest
          ObjPtr = (*its); // set ObjPtr to point to the object
        }
      }
    } else if((*its)->getType() == polyhedron){
      Polyhedron *shape = dynamic_cast<Polyhedron*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          tClosest = t; 
          ObjPtr = (*its);
        }
      }
    } else if((*its)->getType() == triangleMesh){
      TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          tClosest = t;
          ObjPtr = (*its); 
        }
      }
    }
  }
  
  
  if (ObjPtr != NULL) {
    SurFinish appearance = ObjPtr->getSurFin();
    float Kr = appearance.reflective; // reflectivity
    float Kt = appearance.transmission; // transmitivity
    float ior_obj = appearance.ior; // index of refraction
    
    pt = ray.calcDest(tClosest); // set the pos variable pt to the nearest intersection point
    normal = ObjPtr->calcNorm(pt); // normal of intersection point
    if (normal.dot(ray.getDir()) > 0) normal = normal * (-1);
    if(inside) normal = normal * (-1);
    local.setVec(0.0, 0.0, 0.0); // set local shading to black 
    
    // for each light source in the scene
    for (LightIter itl = scene.lights.begin(); itl != scene.lights.end(); itl++){
      Light *LightPtr = (*itl); // pointer to the light source
      
      // calculate local shading according to Phong model
      local = local + phongModel(pt, normal, LightPtr, ObjPtr, ray) / scene.numL;
      
      // Recursively cast reflected and refracted rays
      if (Kr > 0) { // specular reflective
        Ray refl = reflect(ray, pt, normal);
        refl.ObjPtr = ObjPtr;
        reflected = reflected + trace(refl, depth-1)/scene.numL;
      }
      if (Kt > 0 && ior_obj != 0) { // translucent
        Ray refr = transmit(ray, pt, normal, ior_air, ior_obj);
        refr.ObjPtr = ObjPtr;
        transmitted = transmitted + trace(refr, depth-1)/scene.numL;
      }
    }
    
    // update light color
    color.setVec(local + reflected * Kr + transmitted * Kt);
  }
  // if no intersection
  else {
    color.setVec(background); // set color to background color
  }
  
  if (debugMode == 1) {
    printf("\nPrinting information for depth = %d\n", depth);
    Vec orig = ray.getOrig();
    Vec dir = ray.getDir();
    printf("RAY:\n");
    printf("origin = %f %f %f\n", orig.x, orig.y, orig.z);
    printf("direction = %f %f %f\n", dir.x, dir.y, dir.z);
    printf("INTERSECTION:\n");
    printf("intersection point = %f %f %f\n", pt.x, pt.y, pt.z);
    printf("normal = %f %f %f\n", normal.x, normal.y, normal.z);
    printf("LIGHT VISIBILITY:\n");
    printf("local shading = %f %f %f\n", local.x, local.y, local.z);
    printf("reflected shading = %f %f %f\n", reflected.x, reflected.y, reflected.z);
    printf("transmitted shading = %f %f %f\n", transmitted.x, transmitted.y, transmitted.z);
    printf("PIXEL COLOR:\n");
    printf("color = %f %f %f\n", color.x, color.y, color.z);
    printf("\n");
  }
  
  return color;
}
Example #11
0
void IntersectionUI::writeTest() const {
    // creates a deterministic sequence of ray positions and directions
    // and writes the resulting intersections to a file
    // you must add the proper intersect calls for this file to be generated
    
    double invBase[5] = {1.0 / 2.0, 1.0 / 3.0, 1.0 / 5.0, 1.0 / 7.0, 1.0 / 11.0};
    double values[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
    std::ofstream file("../intersections.txt");
    file.precision(4);

    const int seed = static_cast<int>(intersectionUI->m_iSeed->value());
    // generate a halton sequence to pick position/ray combinations
    // skip the first 'seed' values
    for (int i = 0; i < seed; i++) {
        for (int j = 0; j < 5; j++) {
            double r = 1.0 - values[j] - 1e-10;
            if (invBase[j] < r)
                values[j] += invBase[j];
            else {
                double hh;
                double h = invBase[j];
                do {
                    hh = h;
                    h *= invBase[j];
                } while (h >= r);
                values[j] += ((hh + h) - 1.0);
            }
        }
    }
    for (int i = seed; i < (seed + 1638); i++) {
        for (int j = 0; j < 5; j++) {
            double r = 1.0 - values[j] - 1e-10;
            if (invBase[j] < r)
                values[j] += invBase[j];
            else {
                double hh;
                double h = invBase[j];
                do {
                    hh = h;
                    h *= invBase[j];
                } while (h >= r);
                values[j] += ((hh + h) - 1.0);
            }
        }
        // create the ray from the five random values
        // compute ray origin
        Point3 p;
        p[0] = values[4] * sin(values[0] * M_PI) * cos(values[1] * 2.0 * M_PI);
        p[1] = values[4] * sin(values[0] * M_PI) * sin(values[1] * 2.0 * M_PI);
        p[2] = values[4] * cos(values[0] * M_PI);
        // compute ray direction
        Vector3 dir;
        dir[0] = sin(values[2] * M_PI) * cos(values[3] * 2.0 * M_PI);
        dir[1] = sin(values[2] * M_PI) * sin(values[3] * 2.0 * M_PI);
        dir[2] = cos(values[2] * M_PI);
        
        HitRecord cubeHr, cylinderHr, coneHr, sphereHr;
        // ToDo: intersect with your shapes here and store the result
        // in the appropriate hit record
        //cube.intersect(p, dir);
		Cube cube = Cube(1);
		cubeHr = *(cube.intersect(p, dir));
        //cylinder.intersect(p, dir);
		Cylinder cylinder = Cylinder(1, 1);
		cylinderHr = *(cylinder.intersect(p, dir));
        //coneHr = cone.intersect(p, dir);
		Cone cone = Cone(1, 1);
		coneHr = *(cone.intersect(p, dir));
        //sphereHr = sphere.intersect(p, dir);
		Sphere sphere = Sphere(1);
		sphereHr = *(sphere.intersect(p, dir));

        // write out
        file << i << " Cube     " << cubeHr     << std::endl;
        file << i << " Cylinder " << cylinderHr << std::endl;
        file << i << " Cone     " << coneHr     << std::endl;
        file << i << " Sphere   " << sphereHr   << std::endl;
    }
    file.close();
}