rgb Ray_Trace(int obj_num,float dx, float dy,float dz, points from, int depth)
{
	int	    shadow_flag;
	int	    texture, buf_ptr  = 0;
	int     num_image = 1;
	float	nx, ny, nz;
	float	t_min, t1, t2, ipx = 0, ipy = 0, ipz = 0;
	float   rlx, rly, rlz, rfx,rfy,rfz;
	rgb		rgb_color;

	/*  Check if the current ray intercepts spheres */
	t_min = 999.0;
	//obj_num = 0;
	texture = 0;

	for(int i = 1; i <= NUM_SPHERES; i++)
	{
		Check_Sphere(from.x, from.y, from.z, dx, dy, dz, c[i-1][0], 
				c[i-1][1], c[i-1][2], c[i-1][3], &t1, &t2);

		if (t1>=0.00001) {
			t_min = t1;
			obj_num = i;
			Compute_Intersection(from.x, from.y, from.z, 
					dx, dy, dz, t1, &ipx, &ipy, &ipz);
		}

		if (t2>=0.00001 && t2<t_min) {
			t_min = t2;
			obj_num = i;
			Compute_Intersection(from.x, from.y, from.z, 
					dx, dy, dz, t2, &ipx, &ipy, &ipz);
		}

	}
	
	/*  Check if the current ray intercepts planes.  */
	for(int i = 1; i <= NUM_PLANES; i++)
	{
		Check_Plane(from.x, from.y, from.z, dx, dy, dz, p[i-1][0], p[i-1][1], p[i-1][2], p[i-1][3], &t1);

		if (t1 >= 0.00001 && t1<t_min) {
			/*  Check if the intersection point is inside the min/max values. */

			Compute_Intersection(from.x, from.y, from.z, 
					dx, dy, dz, t1, &ipx, &ipy, &ipz);

			if (ipx >= pminmax[i-1][0][0] && ipx <= pminmax[i-1][0][1] && 
				ipy >= pminmax[i-1][1][0]  && ipy <= pminmax[i-1][1][1] && 
				ipz >=  pminmax[i-1][2][0] && ipz <= pminmax[i-1][2][1] ) { 

					t_min = t1;
					obj_num = i+NUM_SPHERES;
			}
		}
	}

	int grain;
	float u,v,w,t,value,x;

	/* Compute the intensity to use at the current pixel.  */
    switch (obj_num) {

	/*  The current ray does not intersect any of the objects.  */
    case 0 :rgb_color.r = 0.1;
			rgb_color.g = 0.1;
			rgb_color.b = 0.1;
			break;

	/*  The current ray intercept sphere #1.  */
	case 1 : 
			nx = ipx - c[0][0];
			ny = ipy - c[0][1];
			nz = ipz - c[0][2];
			Normalize(&nx, &ny, &nz);
					 
			shadow_flag = 0;
			shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num);
			texture = 0;

			
			rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[0], kd_S[0], ks_S[0], ns_S[0], krg_S[0], ktg_S[0], 1);
			
		    break;

	/*  The current ray intercepts sphere #2.  */
	case 2 : 
			nx = ipx - c[1][0];
			ny = ipy - c[1][1];
			nz = ipz - c[1][2];
			Normalize(&nx, &ny, &nz);
			shadow_flag = 0;
			shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num);
					
		    texture = rand() % 2;
			
			if(texture == 1)
			{
				Bump_map(ipx,ipy,ipz,dx,dy,dz,1,&nx,&ny,&nz,2);
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[1], kd_S[1], ks_S[1], ns_S[1], krg_S[1], ktg_S[1], 1);
			}
			else
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[1], kd_S[1], ks_S[1], ns_S[1], krg_S[1], ktg_S[1], 1);
		    break;

	/*  The current ray intercepts sphere #3.  */
	case 3 : 
			nx = ipx - c[2][0];
			ny = ipy - c[2][1];
			nz = ipz - c[2][2];
			Normalize(&nx, &ny, &nz);
			shadow_flag = 0;
			shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num);	 
			texture = rand() % 2;

		    if (texture==1) // Compute texture. */
			{
				Bump_map(ipx,ipy,ipz,dx,dy,dz,1,&nx,&ny,&nz,1);
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka3, tkd3, ks_S[2], ns_S[2], krg_S[2], ktg_S[2], 1);
			}
			else
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[2], kd_S[2], ks_S[2], ns_S[2], krg_S[2], ktg_S[2], 1);
			break;
    
	case 4 :  /*  The current ray intercepts plane #1.  */
			nx = p[0][0];
		    ny = p[0][1];
			nz = p[0][2];
			shadow_flag = 0;
			shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num);	

			grain = wood_grain(ipx,ipy,ipz);

			if(grain < 3)
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka4 ,tkd4 , ks_P[0], ns_P[0] ,krg_P[0], ktg_P[0], 1);
			else
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[0], kd_P[0], ks_P[0], ns_P[0], krg_P[0], ktg_P[0], 1);
			break;
			 
   case 5 :  /*  The current ray intercepts plane #2.  */
			nx = p[1][0];
			ny = p[1][1];
			nz = p[1][2];
			shadow_flag = 0;
			shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num);	
					
			if (ipz < 2.0 || (ipz>=4.0 && ipz<6.0)) {
				if ((ipy>=2.0 && ipy<4.0) || (ipy>=6.0))
					texture = 1;
				else
					texture = 0;
			}
			else {
				if ((ipy<2.0) || (ipy>=4.0 && ipy<6.0)) 
					texture = 1;
				else
					texture = 0;
			}
			if (texture == 1)
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka5, tkd5, ks_P[1], ns_P[1], krg_P[1], ktg_P[1], 1);
			else
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[1], kd_P[1], ks_P[1], ns_P[1], krg_P[1], ktg_P[1], 1);
			break;

	case 6 : /*  The current ray intercepts plane #3.  */
			nx = p[2][0];
			ny = p[2][1];
		    nz = p[2][2];

			shadow_flag = 0;
		    shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num);	
	
			if (ipx < 2.0 || (ipx >= 4.0 && ipx < 6.0)) {
			     if ((ipz >= 2.0 && ipz < 4.0) || (ipz >=6.0))
					texture = 1;
				else
					texture = 0;
			}
			else {
				 if ((ipz<2.0) || (ipz>=4.0 && ipz<6.0)) 
					texture = 1;
				 else
					texture = 0;
			}
			t = turbulence(ipx,ipy,ipz,0.5);
			value = ipx+t;
			x = sqrt( value + 1.0)*0.7071;
			get_marble_color( (float)sin(value*3.1415926), &rgb_color);
			get_marble_color( (float)sin(value*3.1415926), &rgb_color);
			get_marble_color( (float)sin(value*3.1415926), &rgb_color);
			
			/*if (texture == 1)
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka6, tkd6, ks_P[2], ns_P[2], krg_P[2], ktg_P[2], 1);
			else
				rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[2], kd_P[2], ks_P[2], ns_P[2], krg_P[2], ktg_P[2], 1);
			*/
			break;

		default:
			break;
	}

	if(depth < MAX_DEPTH)
	{
		if(obj_num > 0 && obj_num !=4 && nx >= 0 && ny >= 0 && nz >= 0)
		{
			compute_reflected_ray(dx, dy, dz, nx, ny, nz, &rlx, &rly, &rlz);

			points newFrom;
			newFrom.x = ipx;
			newFrom.y = ipy;
			newFrom.z = ipz;
			rgb rcolor = Ray_Trace(obj_num,rlx,rly,rlz,newFrom,depth+1);
			switch(obj_num)
			{
				case 1:
					rgb_color.r += krg_S[0]*rcolor.r;
					rgb_color.g += krg_S[0]*rcolor.g;
					rgb_color.b += krg_S[0]*rcolor.b;
					break;

				case 2:
					rgb_color.r += krg_S[1]*rcolor.r;
					rgb_color.g += krg_S[1]*rcolor.g;
					rgb_color.b += krg_S[1]*rcolor.b;
					break;

				case 3:
					rgb_color.r += krg_S[2]*rcolor.r;
					rgb_color.g += krg_S[2]*rcolor.g;
					rgb_color.b += krg_S[2]*rcolor.b;
					break;
			  
				case 4:
					rgb_color.r += krg_P[0]*rcolor.r;
					rgb_color.g += krg_P[0]*rcolor.g;
					rgb_color.b += krg_P[0]*rcolor.b;
					break;

				case 5:
					rgb_color.r += krg_P[1]*rcolor.r;
					rgb_color.g += krg_P[1]*rcolor.g;
					rgb_color.b += krg_P[1]*rcolor.b;
					break;
			
				case 6:
					rgb_color.r += krg_P[2]*rcolor.r;
					rgb_color.g += krg_P[2]*rcolor.g;
					rgb_color.b += krg_P[2]*rcolor.b;
					break;

				default:
					break;
			}
	    }

		float n1 = 1.0003; /*refractive index air*/
		/*nt -  refractive index material*/
		float thetha = 1000;

		if(obj_num > 0 && obj_num < 7)
		{
			if(obj_num < 4)
			{
				thetha = asin((float)n1/(float)nt_S[obj_num-1]);
				
				if(thetha < 41.2) /* Check if object is semi transparent */
				{
					points newFrom;
					newFrom.x = ipx;
					newFrom.y = ipy;
					newFrom.z = ipz;
			
					compute_refracted_ray(dx,dy,dz,nx,ny,nz,&rfx,&rfy,&rfz,nt_S[obj_num-1]); /*Compute refracted ray*/
					rgb rcolor = Ray_Trace(obj_num,rfx,rfy,rfz,newFrom,depth+1);
					rgb_color.r += ktg_P[0]*rcolor.r;
					rgb_color.g += ktg_P[0]*rcolor.g;
					rgb_color.b += ktg_P[0]*rcolor.b;
				}
			}
			else
			{
				int i = obj_num-NUM_SPHERES-1;
				thetha = asin((float)n1/(float)nt_P[i]);

				if(thetha < 41.2) /* Check if object is semi transparent */
				{
					points newFrom;
					newFrom.x = ipx;
					newFrom.y = ipy;
					newFrom.z = ipz;
			
					compute_refracted_ray(dx,dy,dz,nx,ny,nz,&rfx,&rfy,&rfz,nt_P[i]); /*Compute refracted ray*/
					rgb rcolor = Ray_Trace(obj_num,rfx,rfy,rfz,newFrom,depth+1);
					rgb_color.r += ktg_P[0]*rcolor.r;
					rgb_color.g += ktg_P[0]*rcolor.g;
					rgb_color.b += ktg_P[0]*rcolor.b;
				}
			}
		}
	}
	return rgb_color; 
}
Beispiel #2
0
GimpRGB
get_ray_color_no_bilinear_ref (GimpVector3 *position)
{
  GimpRGB      color_sum;
  GimpRGB      color_int;
  GimpRGB      light_color;
  GimpRGB      color, env_color;
  gint         x;
  gdouble      xf, yf;
  GimpVector3  normal, *p, v, r;
  gint         k;
  gdouble      tmpval;

  pos_to_float (position->x, position->y, &xf, &yf);

  x = RINT (xf);

  if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
    normal = mapvals.planenormal;
  else
    normal = vertex_normals[1][(gint) RINT (xf)];
  gimp_vector3_normalize (&normal);

  if (mapvals.transparent_background && heights[1][x] == 0)
    {
      gimp_rgb_set_alpha (&color_sum, 0.0);
    }
  else
    {
      color = peek (RINT (xf), RINT (yf));
      color_sum = color;
      gimp_rgb_multiply (&color_sum, mapvals.material.ambient_int);

      for (k = 0; k < NUM_LIGHTS; k++)
        {
          p = &mapvals.lightsource[k].direction;

          if (!mapvals.lightsource[k].active
              || mapvals.lightsource[k].type == NO_LIGHT)
            continue;
          else if (mapvals.lightsource[k].type == POINT_LIGHT)
            p = &mapvals.lightsource[k].position;

          color_int = mapvals.lightsource[k].color;
          gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);

              light_color = phong_shade (position,
                                         &mapvals.viewpoint,
                                         &normal,
                                         p,
                                         &color,
                                         &color_int,
                                         mapvals.lightsource[0].type);
        }

      gimp_vector3_sub (&v, &mapvals.viewpoint, position);
      gimp_vector3_normalize (&v);

      r = compute_reflected_ray (&normal, &v);

      /* Get color in the direction of r */
      /* =============================== */

      sphere_to_image (&r, &xf, &yf);
      env_color = peek_env_map (RINT (env_width * xf),
                                RINT (env_height * yf));

      tmpval = mapvals.material.diffuse_int;
      mapvals.material.diffuse_int = 0.;

      light_color = phong_shade (position,
                                 &mapvals.viewpoint,
                                 &normal,
                                 &r,
                                 &color,
                                 &env_color,
                                 DIRECTIONAL_LIGHT);

      mapvals.material.diffuse_int = tmpval;

      gimp_rgb_add (&color_sum, &light_color);
    }

 gimp_rgb_clamp (&color_sum);
 return color_sum;
}