int ar_bezier3_subdivide(struct ar_bezier3 *curve, vec2 *points, int max_n, double max_angle){ vec2 *p = curve->control_points; vec2 v = v2sub(p[1], p[0]); int i; double t = 0.0; double eps = 0.001; vec2 a = p[0]; points[0] = a; for (i = 1; i < max_n - 1; i++){ while (t < 1.0){ t += eps; vec2 b = ar_bezier3_at(curve, t); vec2 w = v2sub(b, a); if (v2angle2(v, w) > max_angle){ points[i] = a; a = b; v = w; break; } } if (t >= 1.0){ break; } } points[i++] = p[3]; return i; }
void Tile2D_AnimTick_Bear(Tile2D_Entity *self) { Tile2D_Entity *tmp; vec2 dir; float h; char *s; int i, j; i=((int)floor(bt2d_state->time_f*4))&1; switch(i) { case 0: s="sprites/tile2d/pedobear_l0"; break; case 1: s="sprites/tile2d/pedobear_l1"; break; } self->spr_tex=LBXGL_Texture_LoadImage(s); if(!(rand()&31) && (v2dist(tile2d_player->org, self->org)<64)) { dir=v2sub(tile2d_player->org, self->org); dir=v2norm(dir); dir=v2scale(dir, 10); // dir=vec2(1*sin(h), 1*cos(h)); // j=((int)floor(bt2d_state->time_f*2))&3; j=rand()&3; // h=(bt2d_state->time_f)*(M_PI/0.1665); tmp=Tile2D_SpawnEntity_Bullet( v2add(self->org, vec2(0, 1)), dir, 0+j); tmp->next=tile2d_entity; tile2d_entity=tmp; tmp->owner=self; } }
void prepare_stencil_segments(const char *path){ FILE *fp = fopen(path, "rb"); assert(fp); int j, m; fscanf(fp, "%d", &m); /* probably less, but memory is cheap */ n_vertices = m*256*3 + 2*3; vertices = malloc(n_vertices*sizeof(*vertices)); struct ar_vertex *vertex_pointer = vertices; struct ar_bezier3 *curves = malloc(m*sizeof(*curves)); for (j = 0; j < m; j++){ float ax, ay, bx, by, cx, cy, dx, dy; fscanf(fp, "%f %f %f %f %f %f %f %f", &ax, &ay, &bx, &by, &cx, &cy, &dx, &dy); ar_bezier3_init(&curves[j], v2(ax, ay), v2(bx, by), v2(cx, cy), v2(dx, dy)); } vec2 p = curves[0].control_points[0]; bounds_x0 = bounds_x1 = p.x; bounds_y0 = bounds_y1 = p.y; for (j = 0; j < m; j++){ int n = 256; vec2 points[n]; n = ar_bezier3_subdivide(&curves[j], points, n, ar_deg2rad(2.0)); int i; vec2 a = points[0]; for (i = 1; i < n; i++){ vec2 b = points[i]; *vertex_pointer++ = ar_vert(p.x, p.y, 0.0f, 0.0f, AR_BLACK); *vertex_pointer++ = ar_vert(a.x, a.y, 0.0f, 0.0f, AR_BLACK); *vertex_pointer++ = ar_vert(b.x, b.y, 0.0f, 0.0f, AR_BLACK); a = b; } } free(curves); n_vertices = vertex_pointer - vertices; int i; for (i = 0; i < n_vertices; i++){ float x = vertices[i].x; float y = vertices[i].y; if (x < bounds_x0) bounds_x0 = x; if (y < bounds_y0) bounds_y0 = y; if (x > bounds_x1) bounds_x1 = x; if (y > bounds_y1) bounds_y1 = y; } ar_make_rect( vertex_pointer, bounds_x0, bounds_y0, bounds_x1, bounds_y1, 0.0f, 0.0f, 0.0f, 0.0f, AR_BLACK); #if 0 double area = 0.0; for (j = 0; j < n_vertices; j += 3){ struct ar_vertex *v = vertices + j; vec2 a = v2(v[0].x, v[0].y); vec2 b = v2(v[1].x, v[1].y); vec2 c = v2(v[2].x, v[2].y); double triangle_area = fabs(0.5*v2det(v2sub(b, a), v2sub(c, a))); if (triangle_area == triangle_area){ area += triangle_area; } } printf("area: %f, %f %% covered\n", area, area*100.0/800/800); #endif }