1 | #include "taichi/ui/gui/gui.h" |
2 | |
3 | namespace taichi { |
4 | |
5 | Vector2 Canvas::Line::vertices[128]; |
6 | |
7 | void Canvas::triangles_batched(int n, |
8 | std::size_t a_, |
9 | std::size_t b_, |
10 | std::size_t c_, |
11 | uint32 color_single, |
12 | std::size_t color_array) { |
13 | auto a = (real *)a_; |
14 | auto b = (real *)b_; |
15 | auto c = (real *)c_; |
16 | auto color_arr = (uint32 *)color_array; |
17 | for (int i = 0; i < n; i++) { |
18 | auto clr = color_single; |
19 | if (color_arr) { |
20 | clr = color_arr[i]; |
21 | } |
22 | triangle_single(a[i * 2], a[i * 2 + 1], b[i * 2], b[i * 2 + 1], c[i * 2], |
23 | c[i * 2 + 1], clr); |
24 | } |
25 | } |
26 | |
27 | void Canvas::paths_batched(int n, |
28 | std::size_t a_, |
29 | std::size_t b_, |
30 | uint32 color_single, |
31 | std::size_t color_array, |
32 | real radius_single, |
33 | std::size_t radius_array) { |
34 | auto a = (real *)a_; |
35 | auto b = (real *)b_; |
36 | auto color_arr = (uint32 *)color_array; |
37 | auto radius_arr = (real *)radius_array; |
38 | for (int i = 0; i < n; i++) { |
39 | auto r = radius_single; |
40 | if (radius_arr) { |
41 | r = radius_arr[i]; |
42 | } |
43 | auto clr = color_single; |
44 | if (color_arr) { |
45 | clr = color_arr[i]; |
46 | } |
47 | // FIXME: path_single seems not displaying correct without the 1e-6 term: |
48 | path_single(a[i * 2], a[i * 2 + 1], b[i * 2] + 1e-6 * (i % 18 + 6), |
49 | b[i * 2 + 1], clr, r); |
50 | } |
51 | } |
52 | |
53 | void Canvas::circles_batched(int n, |
54 | std::size_t x_, |
55 | uint32 color_single, |
56 | std::size_t color_array, |
57 | real radius_single, |
58 | std::size_t radius_array) { |
59 | auto x = (real *)x_; |
60 | auto color_arr = (uint32 *)color_array; |
61 | auto radius_arr = (real *)radius_array; |
62 | for (int i = 0; i < n; i++) { |
63 | auto r = radius_single; |
64 | if (radius_arr) { |
65 | r = radius_arr[i]; |
66 | } |
67 | auto c = color_single; |
68 | if (color_arr) { |
69 | c = color_arr[i]; |
70 | } |
71 | circle(x[i * 2], x[i * 2 + 1]).radius(r).color(c).finish(); |
72 | } |
73 | } |
74 | |
75 | void Canvas::circle_single(real x, real y, uint32 color, real radius) { |
76 | circle(x, y).radius(radius).color(color).finish(); |
77 | } |
78 | |
79 | void Canvas::path_single(real x0, |
80 | real y0, |
81 | real x1, |
82 | real y1, |
83 | uint32 color, |
84 | real radius) { |
85 | path(Vector2(x0, y0), Vector2(x1, y1)).radius(radius).color(color).finish(); |
86 | } |
87 | |
88 | void Canvas::triangle(Vector2 a, Vector2 b, Vector2 c, Vector4 color) { |
89 | a = transform(a); |
90 | b = transform(b); |
91 | c = transform(c); |
92 | |
93 | // real points[3] = {a, b, c}; |
94 | // std::sort(points, points + 3, [](const Vector2 &a, const Vector2 &b) { |
95 | // return a.y < b.y; |
96 | //}); |
97 | Vector2 limits[2]; |
98 | limits[0].x = min(a.x, min(b.x, c.x)); |
99 | limits[0].y = min(a.y, min(b.y, c.y)); |
100 | limits[1].x = max(a.x, max(b.x, c.x)); |
101 | limits[1].y = max(a.y, max(b.y, c.y)); |
102 | for (int i = (int)std::floor(limits[0].x); i < (int)std::ceil(limits[1].x); |
103 | i++) { |
104 | for (int j = (int)std::floor(limits[0].y); j < (int)std::ceil(limits[1].y); |
105 | j++) { |
106 | Vector2 pixel(i + 0.5_f, j + 0.5_f); |
107 | bool inside_a = cross(pixel - a, b - a) <= 0; |
108 | bool inside_b = cross(pixel - b, c - b) <= 0; |
109 | bool inside_c = cross(pixel - c, a - c) <= 0; |
110 | |
111 | // cover both clockwise and counterclockwise case for vertices [a, b, c] |
112 | bool inside_triangle = (inside_a == inside_b) && (inside_a == inside_c); |
113 | |
114 | if (inside_triangle && img.inside(i, j)) { |
115 | img[i][j] = color; |
116 | } |
117 | } |
118 | } |
119 | } |
120 | |
121 | void Canvas::triangle_single(real x0, |
122 | real y0, |
123 | real x1, |
124 | real y1, |
125 | real x2, |
126 | real y2, |
127 | uint32 color_hex) { |
128 | auto a = Vector2(x0, y0); |
129 | auto b = Vector2(x1, y1); |
130 | auto c = Vector2(x2, y2); |
131 | auto color = color_from_hex(color_hex); |
132 | triangle(a, b, c, color); |
133 | } |
134 | |
135 | } // namespace taichi |
136 | |