HIDDEN int fr_miss(struct application *ap) { RT_CK_AP(ap); fr_global_head.pt_forw = fr_global_head.pt_back = &fr_global_head; return 0; }
HIDDEN int fr_hit(struct application *ap, struct partition *headp, struct seg *segp) { RT_CK_AP(ap); RT_CK_PT_HD(headp); if (segp) RT_CK_SEG(segp); if (headp->pt_forw == headp) return 0; /* Steal the linked list, hang it off a global header */ fr_global_head.pt_forw = headp->pt_forw; fr_global_head.pt_back = headp->pt_back; fr_global_head.pt_back->pt_forw = &fr_global_head; fr_global_head.pt_forw->pt_back = &fr_global_head; headp->pt_forw = headp->pt_back = headp; return 1; }
/* * Given a u, v coordinate within the texture (0 <= u, v <= 1.0), * return a pointer to the relevant pixel. * * Note that .pix files are stored left-to-right, bottom-to-top, * which works out very naturally for the indexing scheme. */ HIDDEN int txt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp) { register struct txt_specific *tp = (struct txt_specific *)dp; fastf_t xmin, xmax, ymin, ymax; int dx, dy; register fastf_t r, g, b; struct uvcoord uvc; long tmp; RT_CK_AP(ap); RT_CHECK_PT(pp); uvc = swp->sw_uv; if (rdebug & RDEBUG_SHADE) bu_log("in txt_render(): du=%g, dv=%g\n", uvc.uv_du, uvc.uv_dv); /* take care of scaling U, V coordinates to get the desired amount * of replication of the texture */ uvc.uv_u *= tp->tx_scale[X]; tmp = uvc.uv_u; uvc.uv_u -= tmp; if (tp->tx_mirror && (tmp & 1)) uvc.uv_u = 1.0 - uvc.uv_u; uvc.uv_v *= tp->tx_scale[Y]; tmp = uvc.uv_v; uvc.uv_v -= tmp; if (tp->tx_mirror && (tmp & 1)) uvc.uv_v = 1.0 - uvc.uv_v; uvc.uv_du /= tp->tx_scale[X]; uvc.uv_dv /= tp->tx_scale[Y]; /* * If no texture file present, or if * texture isn't and can't be read, give debug colors */ if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) { bu_log("WARNING: texture [%s] could not be read\n", bu_vls_addr(&tp->tx_name)); VSET(swp->sw_color, uvc.uv_u, 0, uvc.uv_v); if (swp->sw_reflect > 0 || swp->sw_transmit > 0) (void)rr_render(ap, pp, swp); return 1; } /* u is left->right index, v is line number bottom->top */ /* Don't filter more than 1/8 of the texture for 1 pixel! */ if (uvc.uv_du > 0.125) uvc.uv_du = 0.125; if (uvc.uv_dv > 0.125) uvc.uv_dv = 0.125; if (uvc.uv_du < 0 || uvc.uv_dv < 0) { bu_log("txt_render uv=%g, %g, du dv=%g %g seg=%s\n", uvc.uv_u, uvc.uv_v, uvc.uv_du, uvc.uv_dv, pp->pt_inseg->seg_stp->st_name); uvc.uv_du = uvc.uv_dv = 0; } xmin = uvc.uv_u - uvc.uv_du; xmax = uvc.uv_u + uvc.uv_du; ymin = uvc.uv_v - uvc.uv_dv; ymax = uvc.uv_v + uvc.uv_dv; if (xmin < 0) xmin = 0; if (ymin < 0) ymin = 0; if (xmax > 1) xmax = 1; if (ymax > 1) ymax = 1; if (rdebug & RDEBUG_SHADE) bu_log("footprint in texture space is (%g %g) <-> (%g %g)\n", xmin * (tp->tx_w-1), ymin * (tp->tx_n-1), xmax * (tp->tx_w-1), ymax * (tp->tx_n-1)); dx = (int)(xmax * (tp->tx_w-1)) - (int)(xmin * (tp->tx_w-1)); dy = (int)(ymax * (tp->tx_n-1)) - (int)(ymin * (tp->tx_n-1)); if (rdebug & RDEBUG_SHADE) bu_log("\tdx = %d, dy = %d\n", dx, dy); if (dx == 0 && dy == 0) { /* No averaging necessary */ register unsigned char *cp=NULL; if (tp->tx_mp) { cp = ((unsigned char *)(tp->tx_mp->buf)) + (int)(ymin * (tp->tx_n-1)) * tp->tx_w * 3 + (int)(xmin * (tp->tx_w-1)) * 3; } else if (tp->tx_binunifp) { cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) + (int)(ymin * (tp->tx_n-1)) * tp->tx_w * 3 + (int)(xmin * (tp->tx_w-1)) * 3; } else { bu_bomb("sh_text.c -- No texture data found\n"); } r = *cp++; g = *cp++; b = *cp; } else { /* Calculate weighted average of cells in footprint */ fastf_t tot_area = 0.0; fastf_t cell_area; int start_line, stop_line, line; int start_col, stop_col, col; fastf_t xstart, xstop, ystart, ystop; xstart = xmin * (tp->tx_w-1); xstop = xmax * (tp->tx_w-1); ystart = ymin * (tp->tx_n-1); ystop = ymax * (tp->tx_n-1); start_line = ystart; stop_line = ystop; start_col = xstart; stop_col = xstop; r = g = b = 0.0; if (rdebug & RDEBUG_SHADE) { bu_log("\thit in texture space = (%g %g)\n", uvc.uv_u * (tp->tx_w-1), uvc.uv_v * (tp->tx_n-1)); bu_log("\t averaging from (%g %g) to (%g %g)\n", xstart, ystart, xstop, ystop); bu_log("\tcontributions to average:\n"); } for (line = start_line; line <= stop_line; line++) { register unsigned char *cp=NULL; fastf_t line_factor; fastf_t line_upper, line_lower; line_upper = line + 1.0; if (line_upper > ystop) line_upper = ystop; line_lower = line; if (line_lower < ystart) line_lower = ystart; line_factor = line_upper - line_lower; if (tp->tx_mp) { cp = ((unsigned char *)(tp->tx_mp->buf)) + line * tp->tx_w * 3 + (int)(xstart) * 3; } else if (tp->tx_binunifp) { cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) + line * tp->tx_w * 3 + (int)(xstart) * 3; } else { /* not reachable */ bu_bomb("sh_text.c -- Unable to read datasource\n"); } for (col = start_col; col <= stop_col; col++) { fastf_t col_upper, col_lower; col_upper = col + 1.0; if (col_upper > xstop) col_upper = xstop; col_lower = col; if (col_lower < xstart) col_lower = xstart; cell_area = line_factor * (col_upper - col_lower); tot_area += cell_area; if (rdebug & RDEBUG_SHADE) bu_log("\t %d %d %d weight=%g (from col=%d line=%d)\n", *cp, *(cp+1), *(cp+2), cell_area, col, line); r += (*cp++) * cell_area; g += (*cp++) * cell_area; b += (*cp++) * cell_area; } } r /= tot_area; g /= tot_area; b /= tot_area; } if (rdebug & RDEBUG_SHADE) bu_log(" average: %g %g %g\n", r, g, b); if (!tp->tx_trans_valid) { opaque: VSET(swp->sw_color, r / 255.0, g / 255.0, b / 255.0); if (swp->sw_reflect > 0 || swp->sw_transmit > 0) (void)rr_render(ap, pp, swp); return 1; } /* This circumlocution needed to keep expression simple for Cray, * and others */ if (!EQUAL(r, ((long)tp->tx_transp[0]))) goto opaque; if (!EQUAL(g, ((long)tp->tx_transp[1]))) goto opaque; if (!EQUAL(b, ((long)tp->tx_transp[2]))) goto opaque; /* * Transparency mapping is enabled, and we hit a transparent spot. * Let higher level handle it in reflect/refract code. */ swp->sw_transmit = 1.0; swp->sw_reflect = 0.0; bu_log("leaving txt_render()\n"); if (swp->sw_reflect > 0 || swp->sw_transmit > 0) (void)rr_render(ap, pp, swp); return 1; }