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; }
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; }