static void extrude_verts(struct _asset_file *f) { unsigned int i; for(i = 0; i < f->f_hdr->h_verts; i++) { copy_vert(f, i); extrude_vert(f, i); } }
static int clipy(float val, int ismax, const float *v1, const float *v2, int n, float *dst) { float t; int i; int v1o = ismax ? v1[1] > val : v1[1] < val; int v2o = ismax ? v2[1] > val : v2[1] < val; if (v1o + v2o == 0) { /* Both ends of the line are valid - keep v2, v1 will be kept by another call */ copy_vert(dst, v2, n); return 1; } if (v1o + v2o == 2) /* Both ends are invalid - drop both */ return 0; /* It is tempting to spot that the second intersection finding * operation below can be reversed so that it's in the same form as * the first one. Do not do this, as the vagaries of floating point * maths means we get nasty rounding problems. */ if (v2o) { /* v1 valid, v2 invalid - Keep intersection */ t = (val - v1[1]) / (v2[1] - v1[1]); dst[0] = v1[0] + t * (v2[0] - v1[0]); dst[1] = val; for (i = 2; i < n; i++) dst[i] = v1[i] + t * (v2[i] - v1[i]); return 1; } else { /* v2 valid, v1 invalid - Keep intersection, plus v2 */ t = (val - v2[1]) / (v1[1] - v2[1]); dst[0] = v2[0] + t * (v1[0] - v2[0]); dst[1] = val; dst[MAXN] = v2[0]; dst[MAXN+1] = v2[1]; for (i = 2; i < n; i++) { dst[i] = v2[i] + t * (v1[i] - v2[i]); dst[i+MAXN] = v2[i]; } return 2; } }
static int clip_poly(float src[MAXV][MAXN], float dst[MAXV][MAXN], int len, int n, float val, int isy, int ismax) { float cv1[MAXN]; float cv2[MAXN]; int v1, v2, cp; int r; v1 = len - 1; cp = 0; for (v2 = 0; v2 < len; v2++) { copy_vert(cv1, src[v1], n); copy_vert(cv2, src[v2], n); if (isy) r = clipy(val, ismax, cv1, cv2, n); else r = clipx(val, ismax, cv1, cv2, n); switch (r) { case IN: copy_vert(dst[cp++], cv2, n); break; case OUT: break; case LEAVE: copy_vert(dst[cp++], cv2, n); break; case ENTER: copy_vert(dst[cp++], cv1, n); copy_vert(dst[cp++], cv2, n); break; } v1 = v2; } return cp; }
static void fz_paint_triangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n, fz_bbox bbox) { float poly[MAXV][MAXN]; float temp[MAXV][MAXN]; float cx0 = bbox.x0; float cy0 = bbox.y0; float cx1 = bbox.x1; float cy1 = bbox.y1; int gel[MAXV][MAXN]; int ael[2][MAXN]; int del[2][MAXN]; int y, s0, s1, e0, e1; int top, bot, len; int i, k; copy_vert(poly[0], av, n); copy_vert(poly[1], bv, n); copy_vert(poly[2], cv, n); len = clip_poly(poly, temp, 3, n, cx0, 0, 0); len = clip_poly(temp, poly, len, n, cx1, 0, 1); len = clip_poly(poly, temp, len, n, cy0, 1, 0); len = clip_poly(temp, poly, len, n, cy1, 1, 1); if (len < 3) return; for (i = 0; i < len; i++) { gel[i][0] = floorf(poly[i][0] + 0.5f) * 65536; /* trunc and fix */ gel[i][1] = floorf(poly[i][1] + 0.5f); /* y is not fixpoint */ for (k = 2; k < n; k++) gel[i][k] = poly[i][k] * 65536; /* fix with precision */ } top = bot = 0; for (i = 0; i < len; i++) { if (gel[i][1] < gel[top][1]) top = i; if (gel[i][1] > gel[bot][1]) bot = i; } if (gel[bot][1] - gel[top][1] == 0) return; y = gel[top][1]; if (find_next(gel, len, top, &s0, &e0, 1)) return; if (find_next(gel, len, top, &s1, &e1, -1)) return; load_edge(gel, s0, e0, ael[0], del[0], n); load_edge(gel, s1, e1, ael[1], del[1], n); while (1) { int x0 = ael[0][0] >> 16; int x1 = ael[1][0] >> 16; if (ael[0][0] < ael[1][0]) paint_scan(pix, y, x0, x1, ael[0]+2, ael[1]+2, n-2); else paint_scan(pix, y, x1, x0, ael[1]+2, ael[0]+2, n-2); step_edge(ael[0], del[0], n); step_edge(ael[1], del[1], n); y ++; if (y >= gel[e0][1]) { if (find_next(gel, len, e0, &s0, &e0, 1)) return; load_edge(gel, s0, e0, ael[0], del[0], n); } if (y >= gel[e1][1]) { if (find_next(gel, len, e1, &s1, &e1, -1)) return; load_edge(gel, s1, e1, ael[1], del[1], n); } } }