예제 #1
0
/*!
   \brief ADD

   In gsd_surf, tmesh draws polys like so:
   <pre>
   --------------
   |           /|
   |          / |          
   |         /  |         
   |        /   |        
   |       /    |       
   |      /     |      
   |     /      |     
   |    /       |    
   |   /        |   
   |  /         |  
   | /          | 
   |/           |
   --------------
   </pre>

   UNLESS the top right or bottom left point is masked, in which case a
   single triangle with the opposite diagonal is drawn.  This case is
   not yet handled here & should only occur on edges. 
   pt has X & Y coordinates in it, we interpolate Z here

   This could probably be much shorter, but not much faster.   

   \return 1 if point is in view region
   \return otherwise 0 (if masked)
 */
int viewcell_tri_interp(geosurf * gs, typbuff * buf, Point3 pt,
			int check_mask)
{
    Point3 p1, p2, p3;
    int offset, drow, dcol, vrow, vcol;
    float xmax, ymin, ymax, alpha;

    xmax = VCOL2X(gs, VCOLS(gs));
    ymax = VROW2Y(gs, 0);
    ymin = VROW2Y(gs, VROWS(gs));

    if (check_mask) {
	if (gs_point_is_masked(gs, pt)) {
	    return (0);
	}
    }

    if (pt[X] < 0.0 || pt[Y] > ymax) {
	/* outside on left or top */
	return (0);
    }

    if (pt[Y] < ymin || pt[X] > xmax) {
	/* outside on bottom or right */
	return (0);
    }

    if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
	pt[Z] = gs->att[ATT_TOPO].constant;

	return (1);
    }
    else if (MAP_ATT != gs_get_att_src(gs, ATT_TOPO)) {
	return (0);
    }

    vrow = Y2VROW(gs, pt[Y]);
    vcol = X2VCOL(gs, pt[X]);

    if (vrow < VROWS(gs) && vcol < VCOLS(gs)) {
	/*not on bottom or right edge */
	if (pt[X] > 0.0 && pt[Y] < ymax) {
	    /* not on left or top edge */
	    p1[X] = VCOL2X(gs, vcol + 1);
	    p1[Y] = VROW2Y(gs, vrow);
	    drow = VROW2DROW(gs, vrow);
	    dcol = VCOL2DCOL(gs, vcol + 1);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p1[Z]);	/* top right */

	    p2[X] = VCOL2X(gs, vcol);
	    p2[Y] = VROW2Y(gs, vrow + 1);
	    drow = VROW2DROW(gs, vrow + 1);
	    dcol = VCOL2DCOL(gs, vcol);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p2[Z]);	/* bottom left */

	    if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) {
		/* lower triangle */
		p3[X] = VCOL2X(gs, vcol + 1);
		p3[Y] = VROW2Y(gs, vrow + 1);
		drow = VROW2DROW(gs, vrow + 1);
		dcol = VCOL2DCOL(gs, vcol + 1);
		offset = DRC2OFF(gs, drow, dcol);
		GET_MAPATT(buf, offset, p3[Z]);	/* bottom right */
	    }
	    else {
		/* upper triangle */
		p3[X] = VCOL2X(gs, vcol);
		p3[Y] = VROW2Y(gs, vrow);
		drow = VROW2DROW(gs, vrow);
		dcol = VCOL2DCOL(gs, vcol);
		offset = DRC2OFF(gs, drow, dcol);
		GET_MAPATT(buf, offset, p3[Z]);	/* top left */
	    }

	    return (Point_on_plane(p1, p2, p3, pt));
	}
	else if (pt[X] == 0.0) {
	    /* on left edge */
	    if (pt[Y] < ymax) {
		vrow = Y2VROW(gs, pt[Y]);
		drow = VROW2DROW(gs, vrow);
		offset = DRC2OFF(gs, drow, 0);
		GET_MAPATT(buf, offset, p1[Z]);

		drow = VROW2DROW(gs, vrow + 1);
		offset = DRC2OFF(gs, drow, 0);
		GET_MAPATT(buf, offset, p2[Z]);

		alpha = (VROW2Y(gs, vrow) - pt[Y]) / VYRES(gs);
		pt[Z] = LERP(alpha, p1[Z], p2[Z]);
	    }
	    else {
		/* top left corner */
		GET_MAPATT(buf, 0, pt[Z]);
	    }

	    return (1);
	}
	else if (pt[Y] == gs->yrange) {
	    /* on top edge, not a corner */
	    vcol = X2VCOL(gs, pt[X]);
	    dcol = VCOL2DCOL(gs, vcol);
	    GET_MAPATT(buf, dcol, p1[Z]);

	    dcol = VCOL2DCOL(gs, vcol + 1);
	    GET_MAPATT(buf, dcol, p2[Z]);

	    alpha = (pt[X] - VCOL2X(gs, vcol)) / VXRES(gs);
	    pt[Z] = LERP(alpha, p1[Z], p2[Z]);

	    return (1);
	}
    }
    else if (vrow == VROWS(gs)) {
	/* on bottom edge */
	drow = VROW2DROW(gs, VROWS(gs));

	if (pt[X] > 0.0 && pt[X] < xmax) {
	    /* not a corner */
	    vcol = X2VCOL(gs, pt[X]);
	    dcol = VCOL2DCOL(gs, vcol);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p1[Z]);

	    dcol = VCOL2DCOL(gs, vcol + 1);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p2[Z]);

	    alpha = (pt[X] - VCOL2X(gs, vcol)) / VXRES(gs);
	    pt[Z] = LERP(alpha, p1[Z], p2[Z]);

	    return (1);
	}
	else if (pt[X] == 0.0) {
	    /* bottom left corner */
	    offset = DRC2OFF(gs, drow, 0);
	    GET_MAPATT(buf, offset, pt[Z]);

	    return (1);
	}
	else {
	    /* bottom right corner */
	    dcol = VCOL2DCOL(gs, VCOLS(gs));
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, pt[Z]);

	    return (1);
	}
    }
    else {
	/* on right edge, not bottom corner */
	dcol = VCOL2DCOL(gs, VCOLS(gs));

	if (pt[Y] < ymax) {
	    vrow = Y2VROW(gs, pt[Y]);
	    drow = VROW2DROW(gs, vrow);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p1[Z]);

	    drow = VROW2DROW(gs, vrow + 1);
	    offset = DRC2OFF(gs, drow, dcol);
	    GET_MAPATT(buf, offset, p2[Z]);

	    alpha = (VROW2Y(gs, vrow) - pt[Y]) / VYRES(gs);
	    pt[Z] = LERP(alpha, p1[Z], p2[Z]);

	    return (1);
	}
	else {
	    /* top right corner */
	    GET_MAPATT(buf, dcol, pt[Z]);

	    return (1);
	}
    }

    return (0);
}
예제 #2
0
파일: gpd.c 프로젝트: imincik/pkg-grass
/*!
   \brief ADD

   Need to think about translations - If user translates surface,
   sites should automatically go with it, but translating sites should
   translate it relative to surface on which it's displayed

   Handling mask checking here

   \todo prevent scaling by 0 

   \param gp site (geosite)
   \param gs surface (geosurf)
   \param do_fast (unused)

   \return 0
   \return 1
 */
int gpd_2dsite(geosite * gp, geosurf * gs, int do_fast)
{
    float site[3], konst;
    float size;
    int src, check, marker, color;
    geopoint *gpt;
    typbuff *buf;
    GLdouble modelMatrix[16], projMatrix[16];
    GLint viewport[4];
    GLint window[4];


    if (GS_check_cancel()) {
	return (0);
    }

    if (gs) {
	gs_update_curmask(gs);

	src = gs_get_att_src(gs, ATT_TOPO);

	if (src == CONST_ATT) {
	    konst = gs->att[ATT_TOPO].constant;
	}
	else {
	    buf = gs_get_att_typbuff(gs, ATT_TOPO, 0);
	}

	/* Get viewport parameters for view check */
	gsd_getwindow(window, viewport, modelMatrix, projMatrix);

	gsd_pushmatrix();

	gsd_do_scale(1);

	gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);

	gsd_linewidth(gp->width);

	check = 0;
	color = gp->color;
	marker = gp->marker;
	size = gp->size;

	for (gpt = gp->points; gpt; gpt = gpt->next) {
	    if (!(++check % CHK_FREQ)) {
		if (GS_check_cancel()) {
		    gsd_linewidth(1);
		    gsd_popmatrix();

		    return (0);
		}
	    }

	    site[X] = gpt->p3[X] + gp->x_trans - gs->ox;
	    site[Y] = gpt->p3[Y] + gp->y_trans - gs->oy;

	    if (gs_point_is_masked(gs, site)) {
		continue;
	    }

	    /* TODO: set other dynamic attributes */
	    if (gp->attr_mode & ST_ATT_COLOR) {
		color = gpt->iattr;
	    }

	    if (src == MAP_ATT) {
		if (viewcell_tri_interp(gs, buf, site, 1)) {
		    /* returns 0 if outside or masked */
		    site[Z] += gp->z_trans;

		    if (gsd_checkpoint
			(site, window, viewport, modelMatrix, projMatrix))
			continue;
		    else
			/* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(gs, color, size, marker, site); */
			gpd_obj_site_attr(gs, gp, gpt, site);
		}
	    }
	    else if (src == CONST_ATT) {
		if (gs_point_in_region(gs, site, NULL)) {
		    site[Z] = konst + gp->z_trans;
		    if (gsd_checkpoint
			(site, window, viewport, modelMatrix, projMatrix))
			continue;
		    else
			/* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(NULL, color, size, marker, site); */
			gpd_obj_site_attr(NULL, gp, gpt, site);
		}
	    }
	}

	gsd_linewidth(1);
	gsd_popmatrix();
    }

    return (1);
}