/* See {rdo_synthesis_plain.h}. */ #define rdo_synthesis_plain_C_COPYRIGHT "Copyright © 2008 Danillo Pereira and J. Stolfi, UNICAMP" /* Last edited on 2024-12-21 11:50:56 by stolfi */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void rdo_synthesis_plain_compute_image_Diffusion ( solid_vec_t *sds, finish_vec_t *fns, int channel, site_vec_t *pix, double F[] ) { /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *stk = &(pix->e[k]); /* Get its finish {fn}: */ finish_t *fn = rdo_lighting_get_site_finish(stk, sds, fns); F[k] = rdo_finish_get_diffusion_coeff(fn, channel); } } void rdo_synthesis_plain_compute_image_Emission ( solid_vec_t *sds, finish_vec_t *fns, int channel, site_vec_t *pix, double F[] ) { /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *stk = &(pix->e[k]); /* Get its finish {fn}: */ finish_t *fn = rdo_lighting_get_site_finish(stk, sds, fns); F[k] = rdo_finish_get_emission_coeff(fn, channel); } } void rdo_synthesis_plain_compute_image_Normal ( int channel, site_vec_t *pix, double F[] ) { /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *stk = &(pix->e[k]); F[k] = 0.5 + 0.5 * stk->normal.c[channel]; } } void rdo_synthesis_plain_compute_image_Quadrants ( solid_vec_t *sds, int channel, site_vec_t *pix, double F[] ) { /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *sti = &(pix->e[k]); /* Get the solid {sd}: */ int isd = sti->isd; solid_t *sdi = (isd < 0 ? NULL : &(sds->e[isd])); F[k] = rdo_lighting_compute_site_radiance_quadrants(sti, sdi, channel); } } void rdo_synthesis_plain_compute_image_Depth ( solid_vec_t *sds, camera_t *cam, int channel, site_vec_t *pix, double F[] ) { /* Get the scene's bounding box: */ point3_t corner[2]; rdo_solid_vec_bounding_box(sds, corner); /* Get the center {scene_mid} of the scene's box, and its radius vector {scene_rad}: */ point3_t scene_mid; r3_mix(+0.5, &(corner[0]), +0.5, &(corner[1]), &scene_mid); point3_t scene_rad; r3_mix(-0.5, &(corner[0]), +0.5, &(corner[1]), &scene_rad); /* Compute the maximum distance from the camera to the scene: */ double max_dist = r3_dist(&cam->eye, &scene_mid) + r3_norm(&scene_rad); /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *stk = &(pix->e[k]); /* Get the solid objec type {tpSolid}: */ int isd = stk->isd; solid_type_t tpSolid = (isd < 0 ? solid_type_None : sds->e[isd].type); if (tpSolid == solid_type_None) { F[k] = -INF; } else { r3_t epv; r3_sub(&(cam->eye), &(stk->position), &epv); double dist = r3_dot(&epv, &(cam->t)); assert(dist > 0); F[k] = 1.0 - dist/max_dist; } } } void rdo_synthesis_plain_compute_image_SiteDist ( solid_vec_t *sds, camera_t *cam, int des_pix[], double des_val[], int des_n, dist_type_t tpDist, double crossSize, int channel, site_vec_t *pix, double F[] ) { demand(des_n > 0, "must specify at least one reference pixel"); /* Compute the average distance {dmean} from the eye to the selected sites: */ double dmean; { double d2sum = 0.0; int nd = 0; /* Number of valid reference sites. */ int j; for (j = 0; j < des_n; j++) { int ref_pix_i = des_pix[j]; site_t *ref_pix_s = (ref_pix_i < 0 ? NULL : &(pix->e[ref_pix_i])); if ((ref_pix_s != NULL) && (ref_pix_s->isd >= 0)) { double d2 = r3_dist_sqr(&(cam->eye), &(ref_pix_s->position)); d2sum += d2; } } dmean = (nd == 0 ? cam->dist : sqrt(d2sum/nd)); } /* Choose the distance {half_dist} for 1/2 falloff: */ double half_dist = (cam->radius/10)*dmean/cam->dist; /* Loop over the image pixel sites: */ int k; for (k = 0; k < pix->ne; k++) { /* Grab the pixel's site {stk}: */ site_t *stk = &(pix->e[k]); F[k] = 0.0; /* Radiance of pixel {k} in channel {c}. */ int j; for (j = 0; j < des_n; j++) { int ref_pix_i = des_pix[j]; site_t *ref_pix_s = (ref_pix_i < 0 ? NULL : &(pix->e[ref_pix_i])); if ((ref_pix_s != NULL) && (ref_pix_s->isd >= 0)) { double dist = rdo_site_distance(stk, ref_pix_s, tpDist); double dfunc = half_dist/(half_dist + dist); F[k] += des_val[j] * dfunc; } } } } void rdo_synthesis_plain_compute_image ( solid_vec_t *sds, finish_vec_t *fns, camera_t *cam, dist_type_t tpDist, synthesis_options_t *opSyn, int channel, site_vec_t *pix, double F[] ) { fprintf(stderr, "entering {rdo_synthesis_plain_compute_image} ...\n"); fprintf(stderr, "opSyn.imageType = %d\n", opSyn->imageType); /* Get hold of the highlighted pixel sites and sampling sites: */ int des_n = opSyn->highlight_n; /* Count of seleted sites. */ /* int *des_smp = &(opSyn->highlight_smp[0]); */ int *des_pix = &(opSyn->highlight_pix[0]); frgb_t *des_color = &(opSyn->highlight_color[0]); /* Extract the sample values {des_val[0..des_n-1]} for the selected pixels: */ double des_val[des_n]; int jd; for (jd = 0; jd < des_n; jd++) { des_val[jd] = des_color[jd].c[channel]; } switch (opSyn->imageType) { case image_type_Diffusion: { rdo_synthesis_plain_compute_image_Diffusion(sds, fns, channel, pix, F); break; } case image_type_Emission: { rdo_synthesis_plain_compute_image_Emission(sds, fns, channel, pix, F); break; } case image_type_Normal: { rdo_synthesis_plain_compute_image_Normal(channel, pix, F); break; } case image_type_Quadrants: { rdo_synthesis_plain_compute_image_Quadrants(sds, channel, pix, F); break; } case image_type_Depth: { rdo_synthesis_plain_compute_image_Depth(sds, cam, channel, pix, F); break; } case image_type_SiteDist: { double crossSize = 2.0 * opSyn->crossSize; rdo_synthesis_plain_compute_image_SiteDist ( sds, cam, des_pix, des_val, des_n, tpDist, crossSize, channel, pix, F); break; } default: { demand(FALSE, "unexpected image type"); } } }