Example #1
0
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;
}
Example #2
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;
}
Example #3
0
/*
 * 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;
}