Ejemplo n.º 1
0
Vec rayTrace(Ray ray) {
	Vec retorno;
	retorno.x = 0;
	retorno.y = 0;
	retorno.z = 0;

	int indiceObject = objetoMaisProximo(ray);

	//objeto nao encontrado
	if(indiceObject < 0) {
		//para resolver o caso em que os raios que saem do olho (eye) não encontram objetos
		if(ray.depth == 0) {
			retorno.x = arq->background[0];
			retorno.y = arq->background[1];
			retorno.z = arq->background[2];
		}
		//para resolver o caso em que na recursão não se encontra o ponto transmitido ou refletido
		else {
			retorno.x = 0.f;
			retorno.y = 0.f;
			retorno.z = 0.f;
		}
	}
	
	//objeto encontrado
	else {
	
		//cálculo das cores local, refletida e transmitida
		Object object = *arq->objects.at(indiceObject);
		Vec corLocal = shade(object, ray);

		//setando para preto as cores transmitidas e refletidas
		Vec corRefletida;
		corRefletida.x = 0;
		corRefletida.y = 0;
		corRefletida.z = 0;

		Vec corTransmitida;
		corTransmitida.x = 0;
		corTransmitida.y = 0;
		corTransmitida.z = 0;

		//recursao
		if(ray.depth < arq->profundidade) {
			//so executa a recursao caso pretender usar as cores obtidas
			if(object.KS > 0) corRefletida = rayTrace(raioRefletido(object, ray));
			if(object.KT > 0) corTransmitida = rayTrace(raioTransmitido(object, ray));
		}

		//mesclando as cores
		retorno = mesclarCores(object, corLocal, corRefletida, corTransmitida);
	}
	return retorno;
}
Ejemplo n.º 2
0
void GlutCLWindow::glutDisplayCallback() {
    /*
     * Only render the scene to the PBO if the PBO has not been populated yet.
     *
     * TODO: also need to check for changes in the scene content and the camera position, however
     * with animated or interactive scenes we can just always render.  This should be fast enough
     * at some point so that won't be a problem.
     */
    if (reallocPBO) {
        allocatePBO();
        progression = 0;
        rayTrace();
        reallocPBO = false;
        if (maxProgression > 0)
            glutPostRedisplay();
    } else if (progression < maxProgression) {
        /*
         * Progressive refinement, take more samples and accumulate the values into the PBO.
         */
        progression++;
        rayTrace();
        glutPostRedisplay();
    }
    /*
     * Draw PBO to screen as a full-window image.
     */
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glRasterPos2i(0, 0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
    glDrawPixels(width, height, GL_RGBA, GL_FLOAT, 0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    if (reportFPS) {
        if (++frame_counter == fpsAvgFrames) {
            timespec time;
            clock_gettime(CLOCK_REALTIME, &time);
            fps = (double) fpsAvgFrames / (((time.tv_nsec/1000000000.0 + time.tv_sec)  - (last_render_end.tv_nsec/1000000000.0 + last_render_end.tv_sec)));
            frame_counter = 0;
            last_render_end = time;
        }
        std::ostringstream fpsStr;
        fpsStr << "FPS: ";
        fpsStr << fps;
        drawString(0.0f + 20.0f / width, 1.0f - 20.0f / height, fpsStr.str());
    }
    /*
     * Call glFinish() and
     * Flip the back/front buffer
     */
    glutSwapBuffers();

}
tf::Vector3 RayTracePluginUtils::calcNormal(tf::Vector3 start, tf::Vector3 end){
  tf::Vector3 direction = end-start;
  double distance = 0.0005;
  std::vector<tf::Vector3> orthog = getOrthogonalBasis(direction);
  
  tf::Point p1 = start + direction*rayTrace(start, end);
  start = start+orthog[0]*distance;
  end = end+orthog[0]*distance;
  tf::Point p2 = start + direction*rayTrace(start,end);

  start = start+orthog[1]*distance;
  end = end+orthog[1]*distance;
  tf::Point p3 = start + direction*rayTrace(start,end);
  return (p3-p1).cross(p2-p1).normalize();  
}
Ejemplo n.º 4
0
void GLBox::initializeGL()
{
    // this method is called exactly once on program start
    clearImage();

    glViewport(0, 0, m_winWidth, m_winHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-m_winWidth/2, m_winWidth/2, -m_winHeight/2, m_winHeight/2, 0, 1);

    glClear (GL_COLOR_BUFFER_BIT);

    std::cout << "Started..." << std::endl;

    // import .bmp
    Image testImage("C:/GIT/CGProject/input/tiles24.bmp");

    // import .obj
    loadOBJ("C:/GIT/CGProject/input/teapot.obj", faces, &testImage);
    qDebug() << faces.size() << " Faces loaded!";

    for (unsigned int i = 0; (i < faces.size()); i++){
        Tree.Add(&faces[i]);
    }

   // Tree.printTree();

    printf("Sizes: AABB %d; Node %d; Facecount: %u, Nodecount: %u, AABBcount: %u\n", sizeof(AABB), sizeof(Node), (unsigned int)faces.size(), Tree.nodecount, AABB::aabbcount);

    rayTrace();
}
Ejemplo n.º 5
0
void calculate_image(void)
{
	color c;
    Ray ray;
    Uint32 *pixmem32;
    Uint32 sdl_color;
    Uint8 *p;

	for(int i=ImageH-1; i>=0; --i)
    {
        for(int j=ImageW-1;j>=0; --j)
        {
            ray = convertToRay(i, j);
            c = rayTrace(ray, 0);
            c.scale();

            /* Make p point to the place we want to draw the pixel */
            p = (Uint8 *)screen->pixels + ((ImageW - 1) - j) * screen->pitch + i * screen->format->BytesPerPixel;

            /* Draw the pixel! */
            *p=(Uint8)(0xFF * c.b);
            p++;
            *p=(Uint8)(0xFF * c.g);
            p++;
            *p=(Uint8)(0xFF * c.r);
        }
    }


}
/**
 *  Service for Ray tracing in the loaded world.
 */
bool RayTracePluginUtils::rayTrace(gazebo_ray_trace::RayTrace::Request &req,
				   gazebo_ray_trace::RayTrace::Response &resp)
{
  math::Vector3 start, end;

  start.x = req.start.x;
  start.y = req.start.y;
  start.z = req.start.z;

  end.x = req.end.x;
  end.y = req.end.y;
  end.z = req.end.z;



  gazebo::physics::RayShapePtr ray_;
  gazebo::physics::PhysicsEnginePtr engine = world_->GetPhysicsEngine(); 
  engine->InitForThread();

  ray_ = boost::dynamic_pointer_cast<gazebo::physics::RayShape>
    (engine->CreateShape("ray", gazebo::physics::CollisionPtr()));

  // resp.dist = rayTrace(start, end, ray_);
  resp.dist = rayTrace(start, end, ray_);
  // ROS_INFO("Traced ray and responded with distance: %f", resp.dist);
  return true;
}
/**
 *  Ray Traces all particles
 */
std::vector<double> RayTracePluginUtils::rayTraceAllParticles(tf::Point start, 
							      tf::Point end)
{
  tf::Transform trans;
  // ROS_INFO("Setting up ray");
  gazebo::physics::RayShapePtr ray_;
  gazebo::physics::PhysicsEnginePtr engine = world_->GetPhysicsEngine(); 
  engine->InitForThread();

  ray_ = boost::dynamic_pointer_cast<gazebo::physics::RayShape>
    (engine->CreateShape("ray", gazebo::physics::CollisionPtr()));

	   
  std::vector<double> dist;
  dist.resize(particles_.poses.size());
  for(int i=0; i<particles_.poses.size(); i++){

    tf::Vector3 v = tf::Vector3(particles_.poses[i].position.x,
				particles_.poses[i].position.y,
				particles_.poses[i].position.z);
    trans.setOrigin(v);
    tf::Quaternion q;
    tf::quaternionMsgToTF(particles_.poses[i].orientation, q);
    trans.setRotation(q);
    trans = trans.inverse();
	

    dist[i] = rayTrace(vectorTFToGazebo(trans*start), 
				   vectorTFToGazebo(trans*end), 
				   ray_);
  }
  // ROS_INFO("Returning Ray");
  return dist;
}
Ejemplo n.º 8
0
/* calcula uma linha da imagem a cada camada de idle */
int idle_cb(void)
{
	int x;
	/* Faz uma linha de pixels por vez */
	if (yc<height) {
		IupGLMakeCurrent(canvas);
		glBegin(GL_POINTS);
		for( x = 0; x < width; ++x ) {
			Color pixel;
			Vector ray;				

			ray = camGetRay( camera, x, yc );
			pixel = rayTrace( scene, eye, ray, 0 );

			imageSetPixel( image, x, yc, pixel );
			glColor3f((float)pixel.red,(float)pixel.green,(float)pixel.blue);
			glVertex2i(x,yc);

		}
		glEnd();
		glFlush();
		IupGLSwapBuffers(canvas);  /* change the back buffer with the front buffer */
		yc++;
	}
	else {
		IupSetFunction (IUP_IDLE_ACTION, (Icallback) NULL); /* a imagem ja' esta' completa */
		finish_time = clock();
		duration = (double)(finish_time - start_time)/CLOCKS_PER_SEC;
		IupSetfAttribute(label, "TITLE", "tempo=%.3lf s", duration);
	}

	return IUP_DEFAULT;
}
double RayTracePluginUtils::rayTrace(tf::Vector3 start, tf::Vector3 end)
{
  gazebo::physics::RayShapePtr ray_;
  gazebo::physics::PhysicsEnginePtr engine = world_->GetPhysicsEngine(); 
  engine->InitForThread();

  ray_ = boost::dynamic_pointer_cast<gazebo::physics::RayShape>
    (engine->CreateShape("ray", gazebo::physics::CollisionPtr()));
  return rayTrace(vectorTFToGazebo(start), vectorTFToGazebo(end), ray_);
}
Ejemplo n.º 10
0
	void Renderer::renderScene(SceneDesc& desc) {
		if (desc.threadsPow == 0) {
			rayTrace(desc.film, desc.shapeUnion, desc.camera, desc.lights);
			rayTraceReflection(desc.film, &desc.shapeUnion, desc.camera, std::ref(desc.lights), 4);
		}
		else {
			rayTraceConcurrence(desc);
		}
		//parserObj(config["obj"]);
	}
Ejemplo n.º 11
0
/** rayTrace **/
intensity_t rayTrace(scene_t *scene, point_t base, vector_t unitDir,
                 double total_dist, entity_t *self) {
  intensity_t intensity = ((intensity_t){0, 0, 0});
  entity_t * closestEnt;
  hitinfo_t * hit = malloc(sizeof(hitinfo_t));

  closestEnt = closest(scene, base, unitDir, self, hit);
  if (closestEnt == NULL) {
    free(hit);
    return (intensity);
  }

  total_dist += hit->distance;

  window_t * window = ((window_t *)(scene->window->entDerived));
  sobj_t   * sobj   = ((sobj_t   *)(closestEnt->entDerived));

  intensity = ((tuple_t){window->ambient.x * sobj->color.r,
                         window->ambient.y * sobj->color.g,
                         window->ambient.z * sobj->color.b});

  intensity_t light = lighting(scene, closestEnt, hit);
  intensity.x += light.x;
  intensity.y += light.y;
  intensity.z += light.z;

  intensity.x /= 255;
  intensity.y /= 255;
  intensity.z /= 255;
  
  intensity.x /= total_dist;
  intensity.y /= total_dist;
  intensity.z /= total_dist;

  sobj_t * closestSobj = closestEnt->entDerived;
  if (length(((tuple_t)(closestSobj->reflective))) != 0) {
    vector_t U = scale(unitDir, -1);
    vector_t N = hit->normal;
    vector_t V = unitize(add(scale(N, (2 * dot(U, N))), unitDir));

    intensity_t reflection;
    reflection = rayTrace(scene, hit->hitpoint, V, total_dist, closestEnt);

    multiply(reflection, closestSobj->reflective);
    intensity = add(intensity, reflection);
  }


  free(hit);
  return (intensity);

} /* End rayTrace */
Ejemplo n.º 12
0
void Camera::RenderPath(Scene &scn, int n) {
    RayTrace rayTrace(scn);
    
    for (int y = 0; y < _img.YRes; y++) {
        for (int x = 0; x < _img.XRes; x++) {
            
            // compute the primary ray
            Vector3 cy;
            cy.Cross(_worldMatrix.c, _worldMatrix.b);
            Vector3 cx = cy / pow(cy.Magnitude(), 2);
            cy.Cross(cx, _worldMatrix.c);
            
            float hfov = 2.f * atanf(_aspect * tanf(_verticalFOV / 2.f));
            float cw = 2.f * tanf(hfov/2.f);
            float ch = cw / _aspect;
            
            Ray ray;
            ray.Origin = _worldMatrix.d;
            
            ray.Direction =
            _worldMatrix.c + ((float)(x + 0.5f) / (float)_img.XRes - 0.5f) * cw * cx +
            ((float)(y + 0.5f)/(float)_img.YRes - 0.5f) * ch * cy;
            
            ray.type = Ray::PRIMARY;
            
            // shoot the primary ray
            Intersection hit;
            if (x > 124 && x <= 140 && y == _img.YRes - 495 ) {
//                Color white = Color::WHITE;
//                std::cout << "debug pixel" << std::endl;
//                _img.SetPixel(x, y, white.ToInt());
//                continue;
            }
            
            rayTrace.TraceRay(ray, hit);
            
            if (n != -1) {
                Color c;
                c.FromInt(_img.GetPixel(x, y));
                
                Color avg = Color::BLACK;
                avg.AddScaled(c, n - 1);
                avg.Add(hit.Shade);
                avg.Scale(1.0f / n);
                _img.SetPixel(x, y, avg.ToInt());
            }
            else _img.SetPixel(x, y, hit.Shade.ToInt());
        }
    }
    
}
Ejemplo n.º 13
0
RayTraceIterRange rayTrace (const nm::MapMetaData& info, const gm::Point& p1, const gm::Point& p2,
                            bool project_onto_grid, bool project_source_onto_grid, 
                            float max_range)
{

  gm::Point np2 = p2;
  if (max_range > 0) {
    double distance = euclideanDistance(p1,p2);
    if (distance > max_range) {
      np2.x = ((p2.x - p1.x) * max_range/distance) + p1.x;
      np2.y = ((p2.y - p1.y) * max_range/distance) + p1.y;
    }
  }

  Cell c1 = pointCell(info, p1);
  Cell c2 = pointCell(info, np2);
  ROS_DEBUG_STREAM_NAMED ("ray_trace", "Ray tracing between " << c1.x <<
                          ", " << c1.y << " and " << c2.x << ", " << c2.y);
  const RayTraceIterator done(c1, c1, true);
  const RayTraceIterRange empty_range(done, done);
  if (!withinBounds(info, c1)) {
    if (project_source_onto_grid) {
      const optional<Cell> c = rayTraceOntoGrid(info, c2, c1);
      if (c)
        c1 = *c;
      else
        return empty_range;
    }
    else
      throw PointOutOfBoundsException(p1);
  }
  
  if (!withinBounds(info, np2)) {
    if (project_onto_grid) {
      const optional<Cell> c = rayTraceOntoGrid(info, c1, c2);
      if (c)
        c2 = *c;
      else
        return empty_range;
    }
    else {
      throw PointOutOfBoundsException(np2);
    }
  }

  ROS_DEBUG_STREAM_NAMED ("ray_trace", "Projected ray trace endpoints to " << c1.x <<
                          ", " << c1.y << " and " << c2.x << ", " << c2.y);
  return rayTrace(c1, c2);
}
Ejemplo n.º 14
0
void renderPicture()
{
    for(int x = 0; x<ImageW; x++)
    {
        for(int y =0; y<ImageH; y++)
        {
            std::cout<<x<<","<<y<<std::endl;
            position rp = {199,199,-200}; // reference point
            position pixel = {x,y,0};
            ray r = createRay(rp,pixel);
            color c = rayTrace(r, 0);
            setFramebuffer(x,y,c.r,c.g,c.b);
        }
    }
}
Ejemplo n.º 15
0
void App::trace(int x, int y) {
    Color3 sum = Color3::black();
    if (m_currentRays == 1) 
	{
        sum = rayTrace(m_debugCamera->worldRay(x + 0.5f, y + 0.5f, m_currentImage->rect2DBounds()), m_world);
    } 
	// Don't calculate blur if either aperture or focal length are 0
	else if(m_aperture == 0 || m_focalLength == 0)
	{
		for (int i = 0; i < m_currentRays; ++i) 
		{
			sum += rayTrace(m_debugCamera->worldRay(x + rnd.uniform(), y + rnd.uniform(), m_currentImage->rect2DBounds()), m_world);
		}
	}
	else
	{
        for (int i = 0; i < m_currentRays; ++i) {
			// Save the original ray
			Ray oldRay = m_debugCamera->worldRay(x, y, m_currentImage->rect2DBounds());
			
			// Calculate the origin of the new ray by multiplying the x and y values by a fraction of the aperture (keep z the same)
			Point3 newOrigin = Point3(oldRay.origin().x + (rnd.uniform() * m_aperture/20.0f), oldRay.origin().y + (rnd.uniform() * m_aperture/20.0f), oldRay.origin().z);
			 
			// Determine the direction between the end point of the original ray and the new origin
			Vector3 newDirection = ((oldRay.origin() + oldRay.direction()* m_focalLength) - newOrigin);

			// Normalize the direction of the new ray
			newDirection /= newDirection.magnitude();

			// Create a new ray from origin and direction, then add to sum
			Ray newRay = Ray(newOrigin, newDirection);			
            sum += rayTrace(newRay, m_world);
        }
    }
    m_currentImage->set(x, y, sum / (float)m_currentRays);
}
Ejemplo n.º 16
0
/** makePixel **/
pixel_t makePixel(scene_t *scene, int colndx, int rowndx) {
  intensity_t intensity;
  vector_t dir;
  window_t * windowPtr;

  dir = genRay(scene, colndx, rowndx);
  windowPtr = scene->window->entDerived;
  intensity = rayTrace(scene, windowPtr->viewPoint, dir, 0.0, NULL);
  if (intensity.x > 1.0) intensity.x = 1.0;
  if (intensity.y > 1.0) intensity.y = 1.0;
  if (intensity.z > 1.0) intensity.z = 1.0;


  return((pixel_t){(255 * intensity.x),
                   (255 * intensity.y),
                   (255 * intensity.z)});
} /* End makePixel */
Ejemplo n.º 17
0
void pintarTela() {
	for(int i = 0; i < arq->size[0];i++){
		for(int j = 0;j < arq->size[1];j++){
			//criação do raio que sai do olho e passa pelo ponto relativo ao pixel atual
			Ray ray;
			ray.depth = 0;
			ray.org = arq->eye;
			ray.dir = vsub(pixelParaPonto2d(i, j), arq->eye);

			if(i >= 90 && i <= 110 && j >= 80 && j <= 120) {
				int teste = 0;
			}

			//ray trace no pixel atual retornando sua cor para ser pintada na tela
			tela[(i*arq->size[1]) + j] = rayTrace(ray);
		}
	}
}
Ejemplo n.º 18
0
sm::LaserScan::Ptr
simulateRangeScan (const nm::OccupancyGrid& grid, const gm::Pose& sensor_pose,
                   const sm::LaserScan& scanner_info, const bool unknown_obstacles)
{
  sm::LaserScan::Ptr result(new sm::LaserScan(scanner_info));

  const double angle_range = scanner_info.angle_max - scanner_info.angle_min;
  const unsigned n =
    (unsigned) round(1+angle_range/scanner_info.angle_increment);
  const gm::Point& p0 = sensor_pose.position;
  const Cell c0 = pointCell(grid.info, p0);
  const double theta0 = tf::getYaw(sensor_pose.orientation);
  result->ranges.resize(n);

  for (unsigned i=0; i<n; i++)
  {
    const double theta = scanner_info.angle_min+i*scanner_info.angle_increment;
    const gm::Point scan_max =
      rayEndPoint(p0, theta0 + theta, scanner_info.range_max+1);
    
    result->ranges[i] = scanner_info.range_max+1; // Default if loop terminates
    BOOST_FOREACH (const Cell& c, rayTrace(grid.info, p0, scan_max, true))
    {
      const gm::Point p = cellCenter(grid.info, c);
      const double d = sqrt(pow(p.x-p0.x, 2) + pow(p.y-p0.y, 2));
      char data = grid.data[cellIndex(grid.info, c)];
      if (d > scanner_info.range_max)
        break;
      else if (data == OCCUPIED && !(c==c0))
      {
        result->ranges[i] = d;
        break;
      }
      else if (data == UNKNOWN && !(c==c0))
      {
        result->ranges[i] = unknown_obstacles ? d : scanner_info.range_max+1;
        break;
      }
    }
  }

  return result;
}
Ejemplo n.º 19
0
color rayTrace(Ray &ray, int times)
{
	float t = (float)(~(1<<31));
    int iObjectIndex = 0;
    color c, cRefl;
    vect point;
	
    if(times < MAX_REFLECTION_TIMES_LIMIT)
    {
        if(rayIntersect(ray, iObjectIndex, t))
        {
            point = ray.d * t + ray.p0;
            Ray newRay= Ray(point, g_papoObjects[iObjectIndex]->getReflection((-1.0)*ray.d,point));
            cRefl = rayTrace(newRay, times + 1);
            c = getLighting(ray, point,iObjectIndex) *(1 - g_papoObjects[iObjectIndex]->reflPerc)  + g_papoObjects[iObjectIndex]->reflPerc * cRefl;
	    }
    }
	return c;
}
Ejemplo n.º 20
0
/* calcula uma linha da imagem a cada camada de idle */
int idle_cb(void)
{
	int x;
	double ray[VECTOR];
	float pixel[COLOR];

  /* Faz uma linha de pixels por vez */
  if (yc < height) {

    IupGLMakeCurrent(canvas);
    glBegin(GL_POINTS);
    {
      for (x = 0; x < width; ++x) {

        camGetRay(camera, x, yc, ray);
        rayTrace(scene, eye, ray, 0, pixel);

        imageSetPixel(image, x, yc, pixel);
        glColor3f((float) pixel[RED], (float) pixel[GREEN], (float) pixel[BLUE]);
        glVertex2i(x, yc);

      }
    }
    glEnd();

    glFlush();

    IupGLSwapBuffers(canvas);
    
    yc++;
  } else {

		IupSetFunction (IUP_IDLE_ACTION, (Icallback) NULL); /* a imagem ja' esta' completa */
		finish_time = clock();
		duration = (double)(finish_time - start_time)/CLOCKS_PER_SEC;
		IupSetfAttribute(label, "TITLE", "tempo=%.3lf s", duration);

		glFlush();
	}


	return IUP_DEFAULT;
}
Ejemplo n.º 21
0
void MyScene::render(int type, int width, int height, unsigned char* pixels) {
    if (!isLoaded) {
        return;
    }

    // Add your rendering code here.
    // Keep track of your progress as a value between 0 and 1
    // so the progress bar can update as the rendering progresses
	pixelArray = pixels;
	screenWidth = width;
	screenHeight = height;

	//clear the screen
	for (int row = 0; row < height; ++row){
		for (int col = 0; col < width; ++col){
			int i = pxIdx(col, row);
			pixelArray[i] = 0;
			pixelArray[i + 1] = 0;
			pixelArray[i + 2] = 0;
		}
	}

	keepWorking = true;
	renderProgress = 0;

	for (int row = 0; keepWorking && (row < height); ++row){
		for (int col = 0; col < width; ++col){
			Point3 worldCoord = Point3((col + 0.5)*(2 / (double)width) - 1, 1 - (row + 0.5)*(2 / (double)height), -1);
			worldCoord = camera.getCameraToWorld()*worldCoord;

			Point3 eye = camera.getEye();
			Vector3 ray = worldCoord - eye;
			ray.normalize();
			rayTrace(eye, ray);
		}
		renderProgress = (row + 1) / (double)height;
		Fl::check();
	}
}
Ejemplo n.º 22
0
RayTraceIterRange rayTrace (const nm::MapMetaData& info, const gm::Point& p1, const gm::Point& p2,
                            bool project_onto_grid, bool project_source_onto_grid)
{
  Cell c1 = pointCell(info, p1);
  Cell c2 = pointCell(info, p2);
  ROS_DEBUG_STREAM_NAMED ("ray_trace", "Ray tracing between " << c1.x <<
                          ", " << c1.y << " and " << c2.x << ", " << c2.y);
  const RayTraceIterator done(c1, c1, true);
  const RayTraceIterRange empty_range(done, done);
  if (!withinBounds(info, c1)) {
    if (project_source_onto_grid) {
      const optional<Cell> c = rayTraceOntoGrid(info, c2, c1);
      if (c)
        c1 = *c;
      else
        return empty_range;
    }
    else
      throw PointOutOfBoundsException(p1);
  }
  
  if (!withinBounds(info, p2)) {
    if (project_onto_grid) {
      const optional<Cell> c = rayTraceOntoGrid(info, c1, c2);
      if (c)
        c2 = *c;
      else
        return empty_range;
    }
    else {
      throw PointOutOfBoundsException(p2);
    }
  }

  ROS_DEBUG_STREAM_NAMED ("ray_trace", "Projected ray trace endpoints to " << c1.x <<
                          ", " << c1.y << " and " << c2.x << ", " << c2.y);
  return rayTrace(c1, c2);
}
Ejemplo n.º 23
0
Vec3f scene::rayTrace(Vec3f eye, Vec3f dir, int recurseDepth)
{
    //start with black, add color as we go
    Vec3f answer(0,0,0);

    //test for intersection against all our objects
    float dist = myObjGroup->testIntersections(eye, dir);
    //if we saw nothing, return the background color of our scene
    if (dist==9999999)
        return bgColor;

    Vec3f textureColor;

    //get the material index and normal vector(at the point we saw) of the object we saw
    int matIndex = myObjGroup->getClosest()->getMatIndex();
    Vec3f normal = myObjGroup->getClosest()->getNormal(eye, dir * dist);

    //determine texture color

    if (myMaterials.at(matIndex).texture==NULL)
        //this is multiplicative, rather than additive
        //so if there is no texture, just use ones
        textureColor.Set(1,1,1);
    else
    {
        //if there is a texture image, ask the object for the image coordinates (between 0 and 1)
        Vec3f coords = myObjGroup->getClosest()->getTextureCoords(eye, dir * dist);

        //get the color from that image location
        textureColor.Set(
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),0),
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),1),
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),2));
        textureColor = textureColor*(1/255.0);
    }

    // add ambient light/color to our answer
    answer += multiplyColorVectors(ambLight, myMaterials.at(matIndex).diffuseCol);

    // set point slightly above the actual surface, prevents
    // issues with that point intersecting itself
    Vec3f point = eye + (dir * dist) + (normal * .0001);
    Vec3f real_point = eye + (dir * dist);

    // get the diffuse color of our material
    Vec3f diffuseColor = myMaterials.at(matIndex).diffuseCol;

    // iterate through lights
    for (int iter = 0; iter < myLights.size(); iter++) {

        Vec3f lightPos = myLights.at(iter).position;
        Vec3f direction= lightPos - point;

        direction.Normalize();
        float distance = myObjGroup->testIntersections(point, direction);

        // if nothing between point and light
        if (distance == 9999999) {
            Vec3f color = multiplyColorVectors(diffuseColor, myLights.at(iter).color);
            float nl    = abs(direction.Dot3(normal));

            answer += (color * nl);

            // now do the specular
            // we need vector that goes from point to eye
            Vec3f backDir = dir * -1.0f;

            Vec3f h		= (backDir + direction);
            h.Normalize();

            Vec3f Cp	=  myMaterials.at(matIndex).specularCol;
            float p		= myMaterials.at(matIndex).shininess;
            float nh	= abs(normal.Dot3(h));

            nh			= pow(nh, p);
            answer		+= multiplyColorVectors(myLights.at(iter).color, Cp) * nh;
        }
    }
    //if the light can see the surface point,
    //add its diffuse color to a total diffuse for the point (using our illumination model)
    //use testIntersection to help decide this

    //add the diffuse light times the accumulated diffuse light to our answer

    if (recurseDepth < 3) {
        Vec3f e = dir * -1.0f;
        e.Normalize();
        Vec3f r = dir + normal * 2.0f * e.Dot3(normal);
        r.Normalize();

        Vec3f bounced = rayTrace(point, r, recurseDepth + 1);
        answer += (multiplyColorVectors(bounced, myMaterials.at(matIndex).reflectiveCol));

        // refraction
        Vec3f transparentColor	= myMaterials.at(matIndex).transparentCol;
        float transpar			= transparentColor.Dot3(transparentColor);

        if (transpar > 0.0f) {
            float exitAngle, entryAngle;

            if (dir.Dot3(normal) < 0.0f) {
                entryAngle = acos(dir.Dot3(normal * -1.0f));
                exitAngle = entryAngle * myMaterials.at(matIndex).refractionIndex;
            } else {
                entryAngle = acos(dir.Dot3(normal));
                exitAngle = entryAngle / myMaterials.at(matIndex).refractionIndex;
            }

            Vec3f b = (dir + (normal * cos(entryAngle))) * (1.0f /sin(entryAngle));
            b.Normalize();
            Vec3f refracted = (b * sin(exitAngle)) - (normal * cos(exitAngle));
            refracted.Normalize();

            answer += multiplyColorVectors(rayTrace(real_point, refracted, recurseDepth + 1), myMaterials.at(matIndex).transparentCol);
        }
    }
    //put a limit on the depth of recursion
    //if (recurseDepth<3)
    //{
    //reflect our view across the normal
    //recusively raytrace from the surface point along the reflected view
    //add the color seen times the reflective color


    //if going into material (dot prod of dir and normal is negative), bend toward normal
    //find entry angle using inverse cos of dot product of dir and -normal
    //multiply entry angle by index of refraction to get exit angle
    //else, bend away
    //find entry angle using inverse cos of dot product of dir and normal
    //divide entry angle by index of refraction to get exit angle
    //recursively raytrace from the other side of the object along the new direction
    //add the color seen times the transparent color
    //}

    //multiply whatever color we have found by the texture color
    answer=multiplyColorVectors(answer,textureColor);
    return answer;
}
Ejemplo n.º 24
0
RGBAPixel GeometricObject::rayTrace(AreaLight& lightSrc, Point3D& pt, Ray& viewRay, vector<GeometricObject*>& shapes){
    double r = 0.0;
    double g = 0.0;
    double b = 0.0;
    
    int dim = 6;   //6 for testing purposes. 25 for production purposes.
    int total_rays = dim*dim;
    
    vector<Point3D> lightPts = lightSrc.shape.generatePoints(total_rays);
    
    for(int i = 0; i < dim; i++){
        for(int j = 0; j < dim; j++){
            Point3D samplePt(lightPts[i*dim+j]);
            
            Vector3D dir(pt, samplePt); //direction from shape hit point to light source
            dir.normalize();
            Point3D rayPt(pt+(dir*0.01));
            Ray backtraceRay(rayPt,dir, "shadow"); //ray from hit point on shape to light source
            
            double tHitLight = samplePt.distance(rayPt);
            
            bool hitShape = false;
            
            Point3D trash(0,0,0);
            for(int k = 0; k < shapes.size(); k++){
                if(shapes[k] == this)
                    continue;
                double tHitAnotherShape = shapes[k]->hit(backtraceRay,trash);
                if(tHitAnotherShape > 0 && tHitAnotherShape < tHitLight){
                    hitShape = true;
                    break;
                }
            }
            if(!hitShape){
                PointLight ptLt(samplePt, 1, material.kd, material.ks);
                RGBAPixel tempPixel = rayTrace(ptLt, pt, viewRay, shapes);
                r += tempPixel.red;
                g += tempPixel.green;
                b += tempPixel.blue;
            }
            
            r = r*material.directScale;
            g = g*material.directScale;
            b = b*material.directScale;
            
            //Mirror Reflection
            if(viewRay.recurseLevel < 3){
                Vector3D n(this->getNormal(pt));
                Vector3D recViewDir(viewRay.d - (2*viewRay.d*n)*n);
                recViewDir.normalize();
                Ray recViewRay(pt,recViewDir, "view");
                recViewRay.recurseLevel = viewRay.recurseLevel+1;
                Point3D recPt;
                RGBAPixel recColor;
                
                GeometricObject* nextShape = NULL;
                double minTime = 100000.0;
                double tHitAnotherShape = 0.0;
                for(int k = 0; k < shapes.size(); k++){
                    if(shapes[k] == this)
                        continue;
                    
                    tHitAnotherShape = shapes[k]->hit(recViewRay,recPt);
                    if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){
                        nextShape = shapes[k];
                        minTime = tHitAnotherShape;
                    }
                }
                if(nextShape != NULL){
                    recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes);
                    r += (recColor.red);
                    g += (recColor.green);
                    b += (recColor.blue);
                }
            }
        }
    }
    
    
    r = r / total_rays * 1.5;
    g = g / total_rays * 1.5;
    b = b / total_rays * 1.5;
    
    r =std::min((int)r,255);
    g =std::min((int)g,255);
    b =std::min((int)b,255);
    
    RGBAPixel pixel(r,g,b);
    
    
    return pixel;
}
Ejemplo n.º 25
0
int main(int argc, char *argv[])
{
  // Main function for the raytracer. Parses input parameters,
  // sets up the initial blank image, and calls the functions
  // that set up the scene and do the raytracing.
  struct image *im; // Will hold the raytraced image
  struct view *cam; // Camera and view for this scene
  int sx;   // Size of the raytraced image
  int antialiasing; // Flag to determine whether antialiaing is enabled or disabled
  char output_name[1024]; // Name of the output file for the raytraced .ppm image
  struct point3D e;   // Camera view parameters 'e', 'g', and 'up'
  struct point3D g;
  struct point3D up;
  double du, dv;      // Increase along u and v directions for pixel coordinates
  struct point3D pc,d;    // Point structures to keep the coordinates of a pixel and
        // the direction or a ray
  struct ray3D *ray;    // Structure to keep the ray from e to a pixel
  // struct colourRGB col;    // Return colour for raytraced pixels
  struct colourRGB background;   // Background colour
  int i,j;      // Counters for pixel coordinates
  unsigned char *rgbIm;

  if (argc<5)
  {
    fprintf(stderr,"RayTracer: Can not parse input parameters\n");
    fprintf(stderr,"USAGE: RayTracer size rec_depth antialias output_name\n");
    fprintf(stderr,"   size = Image size (both along x and y)\n");
    fprintf(stderr,"   rec_depth = Recursion depth\n");
    fprintf(stderr,"   antialias = A single digit, 0 disables antialiasing. Anything else enables antialiasing\n");
    fprintf(stderr,"   output_name = Name of the output file, e.g. MyRender.ppm\n");
    exit(0);
  }
  sx=atoi(argv[1]);
  MAX_DEPTH=atoi(argv[2]);
  if (atoi(argv[3])==0) antialiasing=0; else antialiasing=1;
    strcpy(&output_name[0],argv[4]);

  fprintf(stderr,"Rendering image at %d x %d\n",sx,sx);
  fprintf(stderr,"Recursion depth = %d\n",MAX_DEPTH);
  if (!antialiasing) fprintf(stderr,"Antialising is off\n");
  else  fprintf(stderr,"Antialising is on\n");
  fprintf(stderr,"Output file name: %s\n",output_name);

  object_list=NULL;
  light_list=NULL;
  texture_list=NULL;

  // Allocate memory for the new image
  im=newImage(sx, sx);
  if (!im)
  {
    fprintf(stderr,"Unable to allocate memory for raytraced image\n");
    exit(0);
  }
  else rgbIm=(unsigned char *)im->rgbdata;

  ///////////////////////////////////////////////////
  // TO DO: You will need to implement several of the
  //        functions below. For Assignment 3, you can use
  //        the simple scene already provided. But
  //        for Assignment 4 you need to create your own
  //        *interesting* scene.
  ///////////////////////////////////////////////////
  buildScene();   // Create a scene. This defines all the
      // objects in the world of the raytracer

  //////////////////////////////////////////
  // TO DO: For Assignment 3 you can use the setup
  //        already provided here. For Assignment 4
  //        you may want to move the camera
  //        and change the view parameters
  //        to suit your scene.
  //////////////////////////////////////////

  // Mind the homogeneous coordinate w of all vectors below. DO NOT
  // forget to set it to 1, or you'll get junk out of the
  // geometric transformations later on.

  // Camera center is at (0,0,-1)
  e.px=0;
  e.py=0;
  e.pz=-1;
  e.pw=1;

  // To define the gaze vector, we choose a point 'pc' in the scene that
  // the camera is looking at, and do the vector subtraction pc-e.
  // Here we set up the camera to be looking at the origin.
  g.px=0-e.px;
  g.py=0-e.py;
  g.pz=0-e.pz;
  g.pw=1;
  // In this case, the camera is looking along the world Z axis, so
  // vector w should end up being [0, 0, -1]

  // Define the 'up' vector to be the Y axis
  up.px=0;
  up.py=1;
  up.pz=0;
  up.pw=1;

  // Set up view with given the above vectors, a 4x4 window,
  // and a focal length of -1 (why? where is the image plane?)
  // Note that the top-left corner of the window is at (-2, 2)
  // in camera coordinates.
  cam=setupView(&e, &g, &up, -1, -2, 2, 4);

  if (cam==NULL)
  {
    fprintf(stderr,"Unable to set up the view and camera parameters. Our of memory!\n");
    cleanup(object_list,light_list, texture_list);
    deleteImage(im);
    exit(0);
  }

  // Set up background colour here
  background.R=0;
  background.G=0;
  background.B=0;

  // Do the raytracing
  //////////////////////////////////////////////////////
  // TO DO: You will need code here to do the raytracing
  //        for each pixel in the image. Refer to the
  //        lecture notes, in particular, to the
  //        raytracing pseudocode, for details on what
  //        to do here. Make sure you undersand the
  //        overall procedure of raytracing for a single
  //        pixel.
  //////////////////////////////////////////////////////
  du=cam->wsize/(sx-1);   // du and dv. In the notes in terms of wl and wr, wt and wb,
  dv=-cam->wsize/(sx-1);    // here we use wl, wt, and wsize. du=dv since the image is
        // and dv is negative since y increases downward in pixel
        // coordinates and upward in camera coordinates.
  colourRGB col;
  point3D origin;
  point3D direction;
  ray3D initialRay;
  colourRGB total;
  int offset;
  int aaSamples;
  fprintf(stderr,"View parameters:\n");
  fprintf(stderr,"Left=%f, Top=%f, Width=%f, f=%f\n",cam->wl,cam->wt,cam->wsize,cam->f);
  fprintf(stderr,"Camera to world conversion matrix (make sure it makes sense!):\n");
  printmatrix(cam->C2W);
  fprintf(stderr,"World to camera conversion matrix:\n");
  printmatrix(cam->W2C);
  fprintf(stderr,"\n");
  fprintf(stderr,"Rendering row: ");
  #pragma omp parallel for schedule(dynamic,32) shared(rgbIm, object_list, light_list, texture_list) private(j)
  for (j=0;j<sx;j++)    // For each of the pixels in the image
  // for (j=2;j<3;j++)
  {
    fprintf(stderr,"%d/%d, ",j,sx);
    #pragma omp parallel for private(origin, direction, col, initialRay, i, aaSamples, offset, total)
    for (i=0;i<sx;i++)
    // for (i=2;i<3;i++)
    {
      if (!antialiasing){
        col.R = 0;
        col.G = 0;
        col.B = 0;
        // = newPoint(cam->wl+i*du,cam->wt+j*dv,cam->f);
        origin.px = cam->wl+i*du;
        origin.py = cam->wt+j*dv;
        origin.pz = cam->f;
        origin.pw = 1.0;
        matVecMult(cam->C2W, &origin);
        // Construct direction vector using Pij - e
        // point3D direction;// = newPoint(origin->px,origin->py, origin->pz);
        direction.px = origin.px;
        direction.py = origin.py;
        direction.pz = origin.pz;
        direction.pw = 1.0;
        subVectors(&e, &direction);
        normalize(&direction);
        // Construct ray using both origin and direction.
        // ray3D initialRay;// = newRay(origin, direction);
        initialRay.p0 = origin;
        initialRay.d = direction;
        // Setting up colors.
        // col = (struct colourRGB *)calloc(1,sizeof(struct colourRGB));

        // Tracing ray
        rayTrace(&initialRay, 1, &col, NULL);
        offset = (sx * j * 3) + (i * 3);
        *(rgbIm + offset + 0) = col.R*255;
        *(rgbIm + offset + 1) = col.G*255;
        *(rgbIm + offset + 2) = col.B*255;
        // Tear down col struct.
        // free(col);
      } else {
        total.R = 0;
        total.G = 0;
        total.B = 0;
        for (aaSamples = 0; aaSamples < 20; aaSamples ++){
          col.R = 0;
          col.G = 0;
          col.B = 0;
          // point3D origin;// = newPoint(cam->wl+i*du,cam->wt+j*dv,cam->f);
          origin.px = cam->wl+(i+drand48()-0.5)*du;
          origin.py = cam->wt+(j+drand48()-0.5)*dv;
          origin.pz = cam->f;
          origin.pw = 1.0;
          matVecMult(cam->C2W, &origin);
          // Construct direction vector using Pij - e
          // point3D direction;// = newPoint(origin->px,origin->py, origin->pz);
          direction.px = origin.px;
          direction.py = origin.py;
          direction.pz = origin.pz;
          direction.pw = 1.0;
          subVectors(&e, &direction);
          normalize(&direction);
          // Construct ray using both origin and direction.
          // ray3D initialRay;// = newRay(origin, direction);
          initialRay.p0 = origin;
          initialRay.d = direction;
          // Setting up colors.
          // col = (struct colourRGB *)calloc(1,sizeof(struct colourRGB));
          // Tracing ray
          rayTrace(&initialRay, 1, &col, NULL);
          total.R += col.R;
          total.G += col.G;
          total.B += col.B;
        }
        offset = (sx * j * 3) + (i * 3);
        total.R = total.R / 20 * 255.0;
        total.G = total.G / 20 * 255.0;
        total.B = total.B / 20 * 255.0;
        *(rgbIm + offset + 0) = total.R;
        *(rgbIm + offset + 1) = total.G;
        *(rgbIm + offset + 2) = total.B;
      }
    } // end for i
  } // end for j
  
  fprintf(stderr,"\nDone!\n");

  // Output rendered image
  imageOutput(im,output_name);

  // Exit section. Clean up and return.
  cleanup(object_list,light_list,texture_list);   // Object, light, and texture lists
  deleteImage(im);          // Rendered image
  free(cam);            // camera view
  exit(0);
}
Ejemplo n.º 26
0
	virtual void		Execute()
	{
		CDB::COLLIDER		DB;
		DB.ray_options		(CDB::OPT_CULL);
		
		xr_vector<RC>		cache;
		{
			RC				rc;	
			rc.C[0].set		(0,0,0); 
			rc.C[1].set		(0,0,0); 
			rc.C[2].set		(0,0,0);
			
			cache.assign	(g_nodes.size()*2,rc);
		}

		FPU::m24r		();
		Query			Q;
		Q.Begin			(g_nodes.size());
		for (u32 N=Nstart; N<Nend; N++)
		{
			// initialize process
			thProgress	= float(N-Nstart)/float(Nend-Nstart);
			vertex&		BaseNode= g_nodes[N];
			Fvector&	BasePos	= BaseNode.Pos;
			Fvector		TestPos = BasePos; TestPos.y+=cover_height;
			
			float	c_total	[8]	= {0,0,0,0,0,0,0,0};
			float	c_passed[8]	= {0,0,0,0,0,0,0,0};
			
			// perform volumetric query
			Q.Init			(BasePos);
			Q.Perform		(N);
			
			// main cycle: trace rays and compute counts
			for (Nearest_it it=Q.q_List.begin(); it!=Q.q_List.end();  it++)
			{
				// calc dir & range
				u32		ID	= *it;
				R_ASSERT	(ID<g_nodes.size());
				if			(N==ID)		continue;
				vertex&		N			= g_nodes[ID];
				Fvector&	Pos			= N.Pos;
				Fvector		Dir;
				Dir.sub		(Pos,BasePos);
				float		range		= Dir.magnitude();
				Dir.div		(range);
				
				// raytrace
				int			sector		=	calcSphereSector(Dir);
				c_total		[sector]	+=	1.f;
				c_passed	[sector]	+=	rayTrace (&DB, TestPos, Dir, range, cache[ID].C); //
			}
			Q.Clear			();
			
			// analyze probabilities
			float	value	[8];
			for (int dirs=0; dirs<8; dirs++)	{
				R_ASSERT(c_passed[dirs]<=c_total[dirs]);
				if (c_total[dirs]==0)	value[dirs] = 0;
				else					value[dirs]	= float(c_passed[dirs])/float(c_total[dirs]);
				clamp(value[dirs],0.f,1.f);
			}
			
			BaseNode.cover	[0]	= (value[2]+value[3]+value[4]+value[5])/4.f; clamp(BaseNode.cover[0],0.f,1.f);	// left
			BaseNode.cover	[1]	= (value[0]+value[1]+value[2]+value[3])/4.f; clamp(BaseNode.cover[1],0.f,1.f);	// forward
			BaseNode.cover	[2]	= (value[6]+value[7]+value[0]+value[1])/4.f; clamp(BaseNode.cover[2],0.f,1.f);	// right
			BaseNode.cover	[3]	= (value[4]+value[5]+value[6]+value[7])/4.f; clamp(BaseNode.cover[3],0.f,1.f);	// back
		}
	}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
void a4_render(// What to render
               SceneNode* root,
               // Where to output the image
               const std::string& filename,
               // Image size
               int width, int height,
               // Viewing parameters
               const Point3D& eye, const Vector3D& view,
               const Vector3D& up, double fov,
               // Lighting parameters
               const Colour& ambient,
               const std::list<Light*>& lights,
               double fogDist
               )
{
  // Fill in raytracing code here.

  std::cerr << "Stub: a4_render(" << root << ",\n     "
            << filename << ", " << width << ", " << height << ",\n     "
            << eye << ", " << view << ", " << up << ", " << fov << ",\n     "
            << ambient << ",\n     {";

  for (std::list<Light*>::const_iterator I = lights.begin(); I != lights.end(); ++I) {
    if (I != lights.begin()) std::cerr << ", ";
    std::cerr << **I;
  }
  std::cerr << "});" << std::endl;

  Vector3D viewVector = view;
  Vector3D upVector = up;
  Vector3D sideVector = viewVector.cross(upVector);
  viewVector.normalize();
  upVector.normalize();
  sideVector.normalize();
  
  Image img(width, height, 3);

  int progress = 0;
  int numPixels = width*height;
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      int newProgress = (int)((double)(y*width + x)/numPixels*100);
      if(newProgress >= progress+5){
        progress = newProgress;
        std::cerr << progress << std::endl;
      }

      double d = height/2.0/tan(toRadian(fov)/2);
      Vector3D dir = (x-(width/2.0))*sideVector + 
          ((height/2.0)-y)*upVector + d*viewVector;
      dir.normalize();
      Ray ray = Ray(eye, dir);

      bool fogOn = true;
      if(fogDist <= 0)
        fogOn = false;
      Colour* color = rayTrace(ambient, eye, ray, root, lights, 5, fogDist);
      Colour fog(1,1,1);
      if(color == NULL) {
        // sunset colours
        Colour horizon(0.94, 0.55, 0.05);
        Colour zenith(0.2, 0.27, 0.4);
        Colour bg = zenith*(1-(double)y/height) + horizon*((double)y/height);
        if(fogOn)
          color = new Colour(0.8,0.8,0.8);
        else
          color = new Colour(bg);
      }

      img(x, y, 0) = color->R();
      img(x, y, 1) = color->G();
      img(x, y, 2) = color->B();
    }
  }
  img.savePng(filename);
  
}
Ejemplo n.º 29
0
Color Union::rayTrace(CRay ray, int depth, CObject* &_object,IntersectResult*& res)
{
    if(depth>max_depth)  return Color::white();
    int size = (int)CVector.size();
    float distance = 100000000.0f;
    CObject* primitive_near = NULL;
    bool visible = true;
    Color totalColor = Color::black();
    CObject* pLight;
    int num=0;
    IntersectResult s = IntersectResult::noHit();
    for(int i=0;i<size;i++){
        CObject* primitive = CVector.at(i);
        IntersectResult result = primitive->isIntersected(ray);
        if(result.isHit){
            if(result.distance < distance){
                s = result;
                distance = result.distance;
                primitive_near = result.object;
                num = i;
            }
        }
    }
    _object = primitive_near;
    res = &s;
    if(primitive_near == NULL) {

        return Color::black();
    }
    else if(primitive_near->isLight()){

        return Color::white();
    }
    else if(!s.front){
        cout<<depth<<" "<<s.object->code<<endl;
        GVector3 v = ray.getDirection();
        v = v.normalize();
        GVector3 normal = s.normal.normalize();
        double cosA = v.dotMul(normal);
        double sinA = sqrt(1-cosA*cosA);
        double n = 1.000 / 1.500;
        //cout<<sinA<<endl;
        if(sinA >= n){
            //cout<<"zhixingle"<<endl;
            CRay newray;
            newray.setDirection(normal*(-cosA) + (ray.getDirection() - normal*cosA).normalize()*sinA);
            newray.setOrigin(s.position + ray.getDirection()*1e-3);
            CObject* no_use = NULL;
            IntersectResult* n0=NULL;
            Color refraction_second = rayTrace(newray,depth+1,no_use,n0);
            //cout<<refraction_second.r<<" "<<refraction_second.g<<" "<<refraction_second.b<<endl;
            Color absorbance(0,0,0);
            if(n0){
                Color absorbance = primitive_near->getMaterial()->getColor().multiply(0.15f * ((-1)*n0->distance));
            }
            Color transparancy = Color(exp(absorbance.r),exp(absorbance.g),exp(absorbance.b));
            return refraction_second.moderate(transparancy);
        }
        else{

            double sinB = sinA / n;

            double cosB = sqrt(1 - sinB*sinB);

            CRay newray;
            newray.setDirection(normal*cosB + (v-normal*cosA).normalize()*sinB);
            newray.setOrigin(s.position + newray.getDirection()*1e-3);
            //cout<<"Origin:"<<newray.getOrigin().getX()<<" "<<newray.getOrigin().getY()<<" "<<newray.getOrigin().getZ()<<endl;
            //cout<<"Direction:"<<newray.getDirection().getX()<<" "<<newray.getDirection().getY()<<" "<<newray.getDirection().getZ()<<endl;
            CObject* no_use = NULL;
            IntersectResult* n0=NULL;
            Color refraction_second = rayTrace(newray,depth+1,no_use,n0);
            //cout<<refraction_second.r<<" "<<refraction_second.g<<" "<<refraction_second.b<<endl;
            Color absorbance(0,0,0);
            if(n0){
                Color absorbance = primitive_near->getMaterial()->getColor().multiply(0.15f * ((-1)*n0->distance));
            }
            Color transparancy = Color(exp(absorbance.r),exp(absorbance.g),exp(absorbance.b));
            return refraction_second.moderate(transparancy);
        }
    }
    else{
        GVector3 point;
        point = ray.getPoint(distance);
        for(int i=0;i<size;i++){
            CObject* primitive = CVector.at(i);
            if(primitive->isLight()){
                pLight = primitive;
                GVector3 inDir = ((Lamp*) primitive)->getCenter() - point;
                inDir = inDir.normalize();
                CRay line(point+inDir*0.001,inDir);
                for(int j=0;j<size;j++){
                    CObject* ano_primitive = CVector.at(j);
                    if(!ano_primitive->isLight() && j!=num){
                        IntersectResult result = ano_primitive->isIntersected(line);
                        if(result.isHit && result.distance < inDir.getLength()){
                            visible = false;
                            break;
                        }
                    }
                }
                break;
            }
        }
    }
    GVector3 point;
    point = ray.getPoint(distance);

    if(visible){
        GVector3 lig = ((Lamp*)pLight)->getCenter() - point;
        lig = lig.normalize();
        primitive_near->getMaterial()->setLightDir(lig);
        totalColor = totalColor.add( primitive_near->getMaterial()->sample(ray, point, primitive_near->getNormal(point)) );
    }
    float reflection = primitive_near->getMaterial()->getRef();
    if( (reflection>0.0f) && (depth<max_depth) ){
        GVector3 normal_point = primitive_near->getNormal(point);
        normal_point = normal_point.normalize();
        float s0 = ray.getDirection().dotMul(normal_point) * (-2.0f);
        CRay newRay;
        newRay.setDirection(normal_point * s0 + ray.getDirection());
        newRay.setOrigin(point + newRay.getDirection()*1e-3);
        CObject* no_use = NULL;
        IntersectResult* n0=NULL;
        Color reflectionColor = rayTrace(newRay,depth+1,no_use,n0);
        reflectionColor = reflectionColor.multiply(reflection);
        //reflectionColor = reflectionColor.moderate(primitive_near->getMaterial()->getColor());
        totalColor = totalColor.add(reflectionColor.moderate(primitive_near->getMaterial()->getColor()));
    }
    float refraction = primitive_near->getMaterial()->getRefr();
    //cout<<refraction<<endl;
    if((refraction>0.0f) && (depth<max_depth)){

        GVector3 normal_point = primitive_near->getNormal(point);
        GVector3 Direction = ray.getDirection().normalize();
        normal_point = normal_point.normalize();
        float cosA = -Direction.dotMul(normal_point);
        float sinA = sqrt(1-cosA*cosA);
        float sinB = sinA / 1.5;
        float cosB = sqrt(1 - sinB*sinB);
        //cout<<sinA<<" "<<cosA<<" "<<sinB<<" "<<cosB<<endl;
        CRay newray;
        newray.setDirection(normal_point*(-cosB) + (Direction + normal_point*cosA).normalize()*sinB);
        newray.setOrigin(point + newray.getDirection() * 1e-3);
        CObject* no_use = NULL;
        IntersectResult* n0=NULL;
        Color refractionColor = rayTrace(newray,depth+1,no_use,n0);
        refractionColor = refractionColor.multiply(refraction);
        //refractionColor = refractionColor.moderate(primitive_near->getMaterial()->getColor());
        totalColor = totalColor.add(refractionColor);
    }
    return totalColor;
}
Ejemplo n.º 30
0
void rtShade(struct object3D *obj, struct point3D *p, struct point3D *n, struct ray3D *ray, int depth, double a, double b, struct colourRGB *col)
{
  // This function implements the shading model as described in lecture. It takes
  // - A pointer to the first object intersected by the ray (to get the colour properties)
  // - The coordinates of the intersection point (in world coordinates)
  // - The normal at the point
  // - The ray (needed to determine the reflection direction to use for the global component, as well as for
  //   the Phong specular component)
  // - The current racursion depth
  // - The (a,b) texture coordinates (meaningless unless texture is enabled)
  //
  // Returns:
  // - The colour for this ray (using the col pointer)
  //
 
  // struct colourRGB tmp_col;     // Accumulator for colour components
  // Apply Ambient Light.
  // Ambient = r_a * I_a * 255
  //         = Albedo_ra * objectColor

  double R,G,B;
  double refractHit = 0;
  double reflectHit = 0;
  double numLights = 0;
  point3D nAdj = *n;
  // printf("RT SHADE CALLED.\n");
  if (obj->texImg==NULL) {
    R = obj->col.R;
    G = obj->col.G;
    B = obj->col.B;
    // printf("PICTURE UNDETECTED. USING R G B = [%f, %f, %f]\n", R,G,B);
  } else {
    // printf("Getting image coordinates @ [%f, %f]\n", a, b);
    // Get object colour from the texture given the texture coordinates (a,b), and the texturing function
    // for the object. Note that we will use textures also for Photon Mapping.
    // printf("CHECKING IMAGE COORDTINATES [%f, %f]\n", a, b);
    obj->textureMap(obj->texImg,a,b,&R,&G,&B);  
    // printf("PICTURE DETECTED. USING A B = [%f, %f]\n", a, b);
    // printf("DONE\n");
  }

  // double numSources = 0.0;
  colourRGB reflectCol, refractCol, tmp_col;
  tmp_col.R = 0; tmp_col.G = 0; tmp_col.B = 0;
  reflectCol.R = 0; reflectCol.G = 0; reflectCol.B = 0;
  refractCol.R = 0; refractCol.G = 0; refractCol.B = 0;
  // Create a ray from light source
  pointLS *lightSource = light_list;
  while (lightSource != NULL){
    // numSources += 1.0;
    // This will hold the colour as we process all the components of
    // the Phong illumination model
    // tmp_col.R=;
    // tmp_col.G=obj->col.G;
    // tmp_col.B=obj->col.B;
    // Set up ray FindFirstHit.

    ray3D lightDirection;// = newRay(p, &lightSource->p0);
    lightDirection.p0 = *p;
    lightDirection.d = lightSource->p0;
    subVectors(p, &lightDirection.d);
    double tempLambda;
    object3D *tempObject;
    point3D tempP;
    point3D tempN;
    // Obtain intersection information.
    findFirstHit(&lightDirection, &tempLambda, obj, &tempObject, &tempP, &tempN, &a, &b);
    if (obj->frontAndBack && dot(&nAdj, &lightDirection.d) < 0){
      nAdj.px = fabs(nAdj.px) * fabs(lightDirection.d.px) / lightDirection.d.px;
      nAdj.py = fabs(nAdj.py) * fabs(lightDirection.d.py) / lightDirection.d.py;
      nAdj.pz = fabs(nAdj.pz) * fabs(lightDirection.d.pz) / lightDirection.d.pz;
    }
    // if (a > 0.0001 && b > 0.0001){
    //   // printf("a, b returned as %f, %f\n", a, b);
    // }
    // Apply Ambient Light.
    // Ambient = r_a * I_a * 255
    //         = Albedo_ra * objectColor
    tmp_col.R += (R * obj->alb.ra * lightSource->col.R);// / NUM_LIGHTS;// lightSource->col.R;// / NUM_LIGHTS;
    tmp_col.G += (G * obj->alb.ra * lightSource->col.G);// / NUM_LIGHTS;// lightSource->col.G;// / NUM_LIGHTS;
    tmp_col.B += (B * obj->alb.ra * lightSource->col.B);// / NUM_LIGHTS;// lightSource->col.B;// / NUM_LIGHTS;
    // printf("AMBIENT LIGHT: [%f, %f, %f]\n", tmp_col.R,tmp_col.G,tmp_col.B);
    // Light source is shining on object if we get here.
    // Set up Phong components:
    point3D s;// = newPoint(lightSource->p0.px - p->px, lightSource->p0.py - p->py, lightSource->p0.pz - p->pz);
    s.px = lightSource->p0.px - p->px;
    s.py = lightSource->p0.py - p->py;
    s.pz = lightSource->p0.pz - p->pz;
    s.pw = 1.0;
    point3D c;// = newPoint(-ray->d.px, -ray->d.py, -ray->d.pz);
    c.px = -ray->d.px;
    c.py = -ray->d.py;
    c.pz = -ray->d.pz;
    c.pw = 1.0;
    subVectors(p, &s);
    // normalize(s);
    point3D m; //= newPoint(2 * dot(s,n) * n->px,
               //           2 * dot(s,n) * n->py,
               //           2 * dot(s,n) * n->pz);
    m.px = 2 * dot(&s,&nAdj) * nAdj.px;
    m.py = 2 * dot(&s,&nAdj) * nAdj.py;
    m.pz = 2 * dot(&s,&nAdj) * nAdj.pz;
    subVectors(&s, &m);
    normalize(&m);
    normalize(&nAdj);
    normalize(&s);
    double dotProduct = dot(&nAdj,&s);

    if (tempLambda < 0.000000001 || tempLambda > 1.0000000){
      // Apply Diffuse
      // Diffuse = r_d * I_d * max(0, n dot s)
      //         = Albedo_rd * lightSource * max(0, n dot s)
      tmp_col.R += (obj->alb.rd * lightSource->col.R * max(0, dotProduct)) * R;// +
      tmp_col.G += (obj->alb.rd * lightSource->col.G * max(0, dotProduct)) * G;// +
      tmp_col.B += (obj->alb.rd * lightSource->col.B * max(0, dotProduct)) * B;// +
      // printf("DIFFUSE LIGHT: [%f, %f, %f]\n", tmp_col.R,tmp_col.G,tmp_col.B);
      // Apply Specular
      // Specular = r_s * I_s * max(0, c dot m) ^ shinyness
      //          = Albedo_rs * lightSource * max(0, c dot m) ^ shinyness
      tmp_col.R += (obj->alb.rs * lightSource->col.R * pow(max(0, dot(&c, &m)), obj->shinyness));
      tmp_col.G += (obj->alb.rs * lightSource->col.G * pow(max(0, dot(&c, &m)), obj->shinyness));
      tmp_col.B += (obj->alb.rs * lightSource->col.B * pow(max(0, dot(&c, &m)), obj->shinyness));
    }
    colourRGB reflectedColor;
    reflectedColor.R = 0; reflectedColor.G = 0; reflectedColor.B = 0;
    if (depth < MAX_DEPTH){
      if (obj->alb.rs > 0){
        // Apply Reflections
        // This involves shooting a ray out from the intersection
        // position and obtaining a colour from that ray.
        // First I will obtain the mirror vector:
        point3D refPoint;// = newPoint(-2.0 * dot(&ray->d, n) * n->px,
                          //           -2.0 * dot(&ray->d, n) * n->py,
                          //           -2.0 * dot(&ray->d, n) * n->pz);
        refPoint.px = -2.0 * dot(&ray->d, &nAdj) * nAdj.px;
        refPoint.py = -2.0 * dot(&ray->d, &nAdj) * nAdj.py;
        refPoint.pz = -2.0 * dot(&ray->d, &nAdj) * nAdj.pz;
        refPoint.pw = 1.0;
        addVectors(&ray->d, &refPoint);
        normalize(&refPoint);
        ray3D refRay;// = newRay(p, refPoint);
        refRay.p0 = *p;
        refRay.d = refPoint;
        // Then I will obtain the colour using mirror vector.
        
        reflectHit ++;
        if (reflectCol.R == 0) {
          rayTrace(&refRay, ++depth, &reflectedColor, tempObject);
          reflectCol.R = obj->alb.rg * reflectedColor.R * R * NUM_LIGHTS;// * lightSource->col.R;
          reflectCol.G = obj->alb.rg * reflectedColor.G * G * NUM_LIGHTS;// * lightSource->col.G;
          reflectCol.B = obj->alb.rg * reflectedColor.B * B * NUM_LIGHTS;// * lightSource->col.B;
        }
        // Clean up created pointers.
        // free(refRay);
        // free(refPoint);
        // DRT Colours
      }
      if (obj->alpha < 1){
        // Apply Refractions
        // This involves shooting a ray out from the intersection
        // position, finding the angle of refraction and then
        // shooting a ray out in that general direction.
        struct point3D vVec, neg_vVec, refractDir, neg_n, neg_d;
        vVec.px = p->px - ray->p0.px; vVec.py = p->py - ray->p0.py; vVec.pz = p->pz - ray->p0.pz;
        neg_vVec.px = - vVec.px; neg_vVec.py = - vVec.py; neg_vVec.pz = - vVec.pz;
        neg_n.px = -nAdj.px; neg_n.py = -nAdj.py; neg_n.pz = -nAdj.pz;
        neg_d.px = -ray->d.px; neg_d.py = -ray->d.py; neg_d.pz = -ray->d.pz;
        refractDir.pw = 1.0;
        if (dot(n, &vVec) < 0){
          // Entering medium
          double nr = 1 / obj->r_index;
          double rootContent = sqrt(1 - pow(nr, 2) * (1 - pow(dot(&neg_vVec, n), 2)));
          if (rootContent >= 0.0) {
            refractDir.px = (nr * (dot(&neg_vVec, &nAdj)- rootContent)*nAdj.px - (nr * neg_vVec.px));
            refractDir.py = (nr * (dot(&neg_vVec, &nAdj)- rootContent)*nAdj.py - (nr * neg_vVec.py));
            refractDir.pz = (nr * (dot(&neg_vVec, &nAdj)- rootContent)*nAdj.pz - (nr * neg_vVec.pz));
          }
        } else {
          // Exiting medium
          double nr = obj->r_index;
          double rootContent = sqrt(1 - pow(nr, 2) * (1-(pow(dot(&neg_n, &neg_d), 2))));
          if (rootContent >= 0.0) {
            refractDir.px = (nr * (dot(&neg_d, &neg_n) - rootContent) * neg_n.px - (nr * neg_d.px));
            refractDir.py = (nr * (dot(&neg_d, &neg_n) - rootContent) * neg_n.py - (nr * neg_d.py));
            refractDir.pz = (nr * (dot(&neg_d, &neg_n) - rootContent) * neg_n.pz - (nr * neg_d.pz));
          }
        }
        ray3D refRay;
        refRay.p0.px = p->px + 0.00009;
        refRay.p0.py = p->py + 0.00009;
        refRay.p0.pz = p->pz + 0.00009;
        refRay.p0.pw = 1.0;
        refRay.d = refractDir;
        colourRGB refractedColor;
        refractedColor.R = 0; refractedColor.G = 0; refractedColor.B = 0;
        // colourRGB refractedColor;
        rayTrace(&refRay, ++depth, &refractedColor, obj);
        refractHit ++;
        refractCol.R += (1 - obj->alpha) * refractedColor.R * R;// * lightSource->col.R;// / NUM_LIGHTS;
        refractCol.G += (1 - obj->alpha) * refractedColor.G * G;// * lightSource->col.G;// / NUM_LIGHTS;
        refractCol.B += (1 - obj->alpha) * refractedColor.B * B;// * lightSource->col.B;// / NUM_LIGHTS;
      }
    }
    // tmp_col.R += reflectCol.R + refractCol.R;// + reflectCol.R + refractCol.R;
    // tmp_col.G += reflectCol.G + refractCol.G;// + reflectCol.G + refractCol.G;
    // tmp_col.B += reflectCol.B + refractCol.B;// + reflectCol.B + refractCol.B;
    // Move pointer to next light source.
    numLights ++;
    lightSource = lightSource->next;
    // Clean up created pointers.
    // free(m);
    // free(s);
    // free(c);
    // free(lightDirection);
  }
 
  // Finally update the color with what we've calculated.

  // col->R = min(drtR/numSources, 1);
  // col->G = min(drtG/numSources, 1);
  // col->B = min(drtB/numSources, 1);
  col->R = min(tmp_col.R + reflectCol.R/fmax(NUM_LIGHTS, 1) + refractCol.R/fmax(refractHit, 1), 1);
  col->G = min(tmp_col.G + reflectCol.G/fmax(NUM_LIGHTS, 1) + refractCol.G/fmax(refractHit, 1), 1);
  col->B = min(tmp_col.B + reflectCol.B/fmax(NUM_LIGHTS, 1) + refractCol.B/fmax(refractHit, 1), 1);
  //   col->R = (n->px + 1) / 2;
  // col->G = (n->py + 1) / 2;
  // col->B = (n->pz + 1) / 2;
  // printf("RTSHADE COMPLETE %f, [%f, %f, %f]\n", numSources, col->R, col->G, col->B);
 
  return;
}