7#include <smk/Shape.hpp>
10 #define M_PI 3.14159265358979323846
15Transformable Shape::FromVertexArray(VertexArray vertex_array) {
16 Transformable drawable;
28 glm::vec2 dt = glm::normalize(glm::vec2(b.y - a.y, -b.x + a.x)) * thickness *
45 if (!vertex_array.
size()) {
47 {{0.F, 0.F}, {0.F, 0.F}},
48 {{1.F, 0.F}, {1.F, 0.F}},
49 {{1.F, 1.F}, {1.F, 1.F}},
50 {{0.F, 0.F}, {0.F, 0.F}},
51 {{1.F, 1.F}, {1.F, 1.F}},
52 {{0.F, 1.F}, {0.F, 1.F}},
56 return FromVertexArray(vertex_array);
62 return Circle(radius, 16 + radius * 0.9);
69 std::vector<Vertex> v;
70 glm::vec2 p1 = glm::vec2(1.0f, 0.0f);
71 glm::vec2 t1 = glm::vec2(0.5F, 0.5F) + 0.5F * p1;
72 glm::vec2 zero(0.F, 0.F);
73 for (
int i = 1; i <= subdivisions; ++i) {
74 float a = float(2.F * M_PI * i) / float(subdivisions);
75 glm::vec2 p2 = glm::vec2(std::cos(a), std::sin(a));
76 glm::vec2 t2 = glm::vec2(0.5F, 0.5F) + 0.5F * p2;
78 v.push_back({zero, zero});
79 v.push_back({radius * p1, t1});
80 v.push_back({radius * p2, t2});
90 constexpr float m = -0.5F;
91 constexpr float z = +0.F;
92 constexpr float p = +0.5F;
93 constexpr float l = 0.F;
94 constexpr float r = 1.F;
96 {{m, m, p}, {z, z, p}, {l, l}}, {{p, m, p}, {z, z, p}, {r, l}},
97 {{p, p, p}, {z, z, p}, {r, r}}, {{m, m, p}, {z, z, p}, {l, l}},
98 {{p, p, p}, {z, z, p}, {r, r}}, {{m, p, p}, {z, z, p}, {l, r}},
100 {{m, m, m}, {z, z, m}, {l, l}}, {{p, p, m}, {z, z, m}, {r, r}},
101 {{p, m, m}, {z, z, m}, {r, l}}, {{m, m, m}, {z, z, m}, {l, l}},
102 {{m, p, m}, {z, z, m}, {l, r}}, {{p, p, m}, {z, z, m}, {r, r}},
104 {{m, p, m}, {z, p, z}, {l, l}}, {{m, p, p}, {z, p, z}, {r, l}},
105 {{p, p, p}, {z, p, z}, {r, r}}, {{m, p, m}, {z, p, z}, {l, l}},
106 {{p, p, p}, {z, p, z}, {r, r}}, {{p, p, m}, {z, p, z}, {l, r}},
108 {{m, m, m}, {z, m, z}, {l, l}}, {{p, m, p}, {z, m, z}, {r, r}},
109 {{m, m, p}, {z, m, z}, {r, l}}, {{m, m, m}, {z, m, z}, {l, l}},
110 {{p, m, m}, {z, m, z}, {l, r}}, {{p, m, p}, {z, m, z}, {r, r}},
112 {{p, m, m}, {p, z, z}, {l, l}}, {{p, p, m}, {p, z, z}, {r, l}},
113 {{p, p, p}, {p, z, z}, {r, r}}, {{p, m, m}, {p, z, z}, {l, l}},
114 {{p, p, p}, {p, z, z}, {r, r}}, {{p, m, p}, {p, z, z}, {l, r}},
116 {{m, m, m}, {m, z, z}, {l, l}}, {{m, p, p}, {m, z, z}, {r, r}},
117 {{m, p, m}, {m, z, z}, {r, l}}, {{m, m, m}, {m, z, z}, {l, l}},
118 {{m, m, p}, {m, z, z}, {l, r}}, {{m, p, p}, {m, z, z}, {r, r}},
123 return transformable;
131 std::vector<glm::vec3> out = {
132 {+1.F, +0.F, +0.F}, {+0.F, +1.F, +0.F}, {+0.F, +0.F, +1.F},
133 {-1.F, +0.F, +0.F}, {+0.F, +0.F, -1.F}, {+0.F, -1.F, +0.F},
134 {+0.F, -1.F, +0.F}, {+1.F, +0.F, +0.F}, {+0.F, +0.F, +1.F},
135 {+0.F, +1.F, +0.F}, {+0.F, +0.F, -1.F}, {-1.F, +0.F, +0.F},
136 {-1.F, +0.F, +0.F}, {+0.F, -1.F, +0.F}, {+0.F, +0.F, +1.F},
137 {+1.F, +0.F, +0.F}, {+0.F, +0.F, -1.F}, {+0.F, +1.F, +0.F},
138 {+0.F, +1.F, +0.F}, {-1.F, +0.F, +0.F}, {+0.F, +0.F, +1.F},
139 {+0.F, -1.F, +0.F}, {+0.F, +0.F, -1.F}, {+1.F, +0.F, +0.F},
142 for (
int i = 0; i < iteration; ++i) {
143 std::vector<glm::vec3> in;
145 for (
unsigned int j = 0; j < in.size();) {
146 glm::vec3& a = in[j++];
147 glm::vec3& b = in[j++];
148 glm::vec3& c = in[j++];
149 glm::vec3 d = glm::normalize(a + b + c);
150 auto addition = {a, b, d, b, c, d, c, a, d};
151 out.insert(out.end(), addition.begin(), addition.end());
155 std::vector<Vertex3D> vertex_array(out.size());
156 for (
auto& it : out) {
157 vertex_array.push_back(
158 {it * 0.5F, it, {it.x * 0.5F + 0.5F, it.y * 0.5F + 0.5F}});
163 return transformable;
168 constexpr float m = -0.5F;
169 constexpr float z = +0.F;
170 constexpr float p = +0.5F;
171 constexpr float l = 0.F;
172 constexpr float r = 1.F;
174 {{m, m, z}, {z, z, p}, {l, l}},
175 {{p, m, z}, {z, z, p}, {r, l}},
176 {{p, p, z}, {z, z, p}, {r, r}},
177 {{m, m, z}, {z, z, p}, {l, l}},
178 {{p, p, z}, {z, z, p}, {r, r}},
179 {{m, p, z}, {z, z, p}, {l, r}},
184 return transformable;
194 size_t subdivision) {
195 std::vector<glm::vec2> path;
196 for (
size_t index = 0; index < subdivision + 1; ++index) {
197 std::vector<glm::vec2> data = points;
198 float x = float(index) / float(subdivision);
199 while (data.size() >= 2) {
200 for (
size_t i = 0; i < data.size() - 1; ++i) {
201 data[i] = glm::mix(data[i], data[i + 1], x);
203 data.resize(data.size() - 1);
205 path.push_back(data[0]);
218 std::vector<glm::vec3> planes_left;
219 std::vector<glm::vec3> planes_right;
225 for (
size_t i = 1; i < points.size(); ++i) {
226 glm::vec3 plane_left =
227 cross(vec3(points[i - 1], 1.F), vec3(points[i - 0], 1.F));
228 glm::vec3 plane_right = plane_left;
229 plane_left.z -= thickness * length(vec2(plane_left.x, plane_left.y));
230 plane_right.z += thickness * length(vec2(plane_right.x, plane_right.y));
231 planes_left.push_back(plane_left);
232 planes_right.push_back(plane_right);
237 std::vector<glm::vec2> points_left;
238 std::vector<glm::vec2> points_right;
242 glm::vec2 direction = normalize(points[1] - points[0]);
243 glm::vec2 normal = {direction.y, -direction.x};
244 points_left.push_back(points[0] - normal * thickness);
245 points_right.push_back(points[0] + normal * thickness);
249 for (
size_t j = 1; j < points.size() - 1; ++j) {
250 glm::vec3 intersection_left = cross(planes_left[i], planes_left[j]);
251 glm::vec3 intersection_right = cross(planes_right[i], planes_right[j]);
252 const float epsilon = 0.01F;
253 if (intersection_left.z * intersection_right.z < epsilon) {
256 intersection_left /= intersection_left.z;
257 intersection_right /= intersection_right.z;
258 auto left = glm::vec2(intersection_left);
259 auto right = glm::vec2(intersection_right);
261 if (glm::distance(left, right) > 10.F * thickness) {
262 auto middle = glm::vec2(left + right) * 0.5F;
264 auto dir = glm::normalize(glm::vec2(right - left)) * 5.F * thickness;
265 left = glm::vec3(middle - dir, 1.F);
266 right = glm::vec3(middle + dir, 1.F);
268 points_left.push_back(left);
269 points_right.push_back(right);
275 glm::vec2 direction = normalize(points[points.size() - 2] - points.back());
276 glm::vec2 normal = {direction.y, -direction.x};
277 points_left.push_back(points.back() + normal * thickness);
278 points_right.push_back(points.back() - normal * thickness);
281 std::vector<smk::Vertex> v;
288 for (
size_t i = 1; i < points_left.size(); ++i) {
289 glm::vec2& A = points_left[i - 1];
290 glm::vec2& B = points_right[i - 1];
291 glm::vec2& C = points_left[i];
292 glm::vec2& D = points_right[i];
294 v.push_back({A, {0.0, 0.0}});
295 v.push_back({B, {0.0, 0.0}});
296 v.push_back({D, {0.0, 0.0}});
297 v.push_back({A, {0.0, 0.0}});
298 v.push_back({D, {0.0, 0.0}});
299 v.push_back({C, {0.0, 0.0}});
312 radius = std::max(radius, 0.F);
313 radius = std::min(radius, width * 0.5F);
314 radius = std::min(radius, height * 0.5F);
316 width = width * 0.5F - radius;
317 height = height * 0.5F - radius;
318 std::vector<smk::Vertex> v;
320 smk::Vertex p1 = {{width + radius, -height}, {0.F, 0.F}};
321 smk::Vertex p2 = {{width + radius, height}, {0.F, 0.F}};
327 const float angle_delta = 2.0 * M_PI / 40.f;
329 auto center = glm::vec2(width, radius);
331 for (
float angle = 0.F; angle < 2.F * M_PI; angle += angle_delta) {
332 if (angle > 0.75 * 2.F * M_PI) {
333 center = glm::vec2(width, -height);
334 }
else if (angle > 0.5 * 2.F * M_PI) {
335 center = glm::vec2(-width, -height);
336 }
else if (angle > 0.25 * 2.F * M_PI) {
337 center = glm::vec2(-width, +height);
339 center = glm::vec2(+width, +height);
343 p2 = {center + radius * glm::vec2(std::cos(angle), std::sin(angle)), {0.F, 0.F}};
351 p2 = {{width + radius, -height}, {0.F, 0.F}};
static Transformable RoundedRectangle(float width, float height, float radius)
Return a rounded centered rectangle. @params width The width of the rectangle. @params height The hei...
static Transformable Line(const glm::vec2 &a, const glm::vec2 &b, float thickness)
Return a line with a given thickness.
static Transformable3D Cube()
Return a centered 1x1x1 3D cube.
static Transformable Path(const std::vector< glm::vec2 > &points, float thickness)
Build a path of a given |thickness| along a sequence of connected lines. @params points The sequence ...
static Transformable Circle(float radius)
Return a circle.
static Transformable3D IcoSphere(int iteration)
A centered sphere.
static Transformable Square()
Return the square [0,1]x[0,1].
static std::vector< glm::vec2 > Bezier(const std::vector< glm::vec2 > &point, size_t subdivision)
Return a bezier curve.
static Transformable3D Plane()
Return a centered 1x1 square in a 3D space.
An array of smk::Vertex moved to the GPU memory. This represent a set of triangles to be drawn by the...
size_t size() const
The size of the GPU array.
The vertex structure suitable for a 2D shader.