diff --git a/psemek b/psemek index a2c8363..c16194c 160000 --- a/psemek +++ b/psemek @@ -1 +1 @@ -Subproject commit a2c83633ae09f3db5c1e4d115a417021d38914ae +Subproject commit c16194c95cf627c14135db8b4da33fa4eb3b759f diff --git a/source/application.cpp b/source/application.cpp index 1b34d1d..54a6f51 100644 --- a/source/application.cpp +++ b/source/application.cpp @@ -697,37 +697,225 @@ namespace gmtk } } + float animation_factor(float animate) + { + static geom::gradient const g + { + std::pair{0.5f, 0.f}, + geom::easing_type::cubic, + std::pair{0.875f, 1.f}, + geom::easing_type::cubic, + std::pair{1.f, 0.f}, + }; + + return g(animate); + } + void draw_structure(geom::box const & bbox, transformer const & t, gfx::painter & painter) { - auto box = geom::shrink(bbox, bbox[0].length() * 0.2f); - - for (int i = 0; i < 2; ++i) + switch (t.type) { - gfx::color_rgba color = {0, 0, 0, 255}; + case transformer_type::mixer: + { + float an = animation_factor(t.animate); - if (i == 1) + auto box = geom::shrink(bbox, bbox[0].length() * 0.2f); + + float r1 = std::sqrt(2.f) * (2.f + 2.f * an) / 16.f * box[0].length(); + float r2 = std::sqrt(2.f) * (4.f + 2.f * an) / 16.f * box[0].length(); + + float s = bbox[0].length() * 0.025f; + float t = 0.6f * s; + + box = geom::expand(box, an * box[0].length() * 0.125f); + + geom::point points[] { - color = {255, 255, 255, 255}; - if (t.type == transformer_type::mixer) - box = geom::shrink(bbox, bbox[0].length() * (0.2f + 0.025f * std::sqrt(2.f))); - else - box = geom::shrink(bbox, bbox[0].length() * 0.225f); + box.corner(0.f, 0.75f), + box.corner(0.f, 0.25f), + box.corner(0.25f, 0.f), + box.corner(0.75f, 0.f), + box.corner(1.f, 0.25f), + box.corner(1.f, 0.75f), + box.corner(0.75f, 1.f), + box.corner(0.25f, 1.f), + }; + + static geom::triangle const triangles[] + { + {0, 1, 2}, + {0, 2, 3}, + {0, 3, 4}, + {0, 4, 5}, + {0, 5, 6}, + {0, 6, 7}, + }; + + for (int i = 0; i < 2; ++i) + { + auto color = (i == 0) ? gfx::black : gfx::white; + + if (i == 1) + { + points[0] += geom::vector{ s, -t}; + points[1] += geom::vector{ s, t}; + points[2] += geom::vector{ t, s}; + points[3] += geom::vector{-t, s}; + points[4] += geom::vector{-s, t}; + points[5] += geom::vector{-s, -t}; + points[6] += geom::vector{-t, -s}; + points[7] += geom::vector{ t, -s}; + } + + for (auto const & t : triangles) + { + auto p0 = points[t[0]]; + auto p1 = points[t[1]]; + auto p2 = points[t[2]]; + + painter.triangle(p0, p1, p2, color); + } } - switch (t.type) + auto c = bbox.center(); + + for (int i = 0; i < 4; ++i) { - case transformer_type::mixer: - painter.triangle(box.corner(0.f, 0.5f), box.corner(1.f, 0.5f), box.corner(0.5f, 0.f), color); - painter.triangle(box.corner(0.f, 0.5f), box.corner(1.f, 0.5f), box.corner(0.5f, 1.f), color); - break; - case transformer_type::reshaper: - painter.rect(box, color); - break; - case transformer_type::hue_shifter: - painter.circle(box.center(), box[0].length() / 2.f, color, 72); - break; + auto d = geom::direction(geom::rad(45.f + 90.f * i)); + painter.line(c + d * r1, c + d * r2, s, gfx::black, true); } } + break; + case transformer_type::reshaper: + { + auto box = geom::shrink(bbox, bbox[0].length() * 0.2f); + + float s = bbox[0].length() * 0.025f; + + for (int k = 0; k < 2; ++k) + { + geom::point points[] + { + box.corner(0.f, 1.f), + box.corner(0.f, 0.75f), + box.corner(0.25f, 0.5f), + box.corner(0.75f, 0.5f), + box.corner(1.f, 0.75f), + box.corner(1.f, 1.f), + }; + + static geom::triangle const triangles[] + { + {0, 1, 2}, + {0, 2, 3}, + {0, 3, 4}, + {0, 4, 5}, + }; + + auto c = bbox.center(); + + for (int i = 0; i < 2; ++i) + { + auto color = (i == 0) ? gfx::black : gfx::white; + + if (i == 1) + { + points[0] += geom::vector{s, -s}; + points[1] += geom::vector{s, 0.6f * s}; + points[2] += geom::vector{0.6f * s, s}; + points[3] += geom::vector{- 0.6f * s, s}; + points[4] += geom::vector{-s, 0.6f * s}; + points[5] += geom::vector{-s, -s}; + } + + for (int j = 0; j < 2; ++j) + { + float d = 1.f - animation_factor(t.animate); + d *= box[0].length() * 0.125f; + if (j == 1) + d = -d; + + for (auto const & t : triangles) + { + auto p0 = points[t[0]]; + auto p1 = points[t[1]]; + auto p2 = points[t[2]]; + + if (j == 1) + { + float m = box[1].min + box[1].max; + p0[1] = m - p0[1]; + p1[1] = m - p1[1]; + p2[1] = m - p2[1]; + } + + p0[1] += d; + p1[1] += d; + p2[1] += d; + + if (k == 0) + { + p0 = c + geom::ort(p0 - c); + p1 = c + geom::ort(p1 - c); + p2 = c + geom::ort(p2 - c); + } + + painter.triangle(p0, p1, p2, color); + } + } + } + } + break; + } + case transformer_type::hue_shifter: + { + float size = bbox[0].length(); + float s = size * 0.025f; + float r1 = size * 0.33f - s / 2.f; + float r2 = r1 * 0.5f - s / 2.f; + + auto c = bbox.center(); + + static geom::gradient const g + { + std::pair{0.5f, 1.f}, + geom::easing_type::cubic, + std::pair{1.f, 0.f}, + }; + + float offset = - g(t.animate) * geom::pi / 3.f; + + int n = 6; + + for (int i = 0; i < n; ++i) + { + float a = (i * 2.f * geom::pi) / n + offset; + float b = ((i + 1) * 2.f * geom::pi) / n + offset; + + auto da = geom::direction(a); + auto db = geom::direction(b); + + painter.triangle(c + da * r2, c + db * r2, c + da * r1, gfx::white); + painter.triangle(c + db * r2, c + da * r1, c + db * r1, gfx::white); + } + + for (int i = 0; i < n; ++i) + { + float a = (i * 2.f * geom::pi) / n + offset; + float b = ((i + 1) * 2.f * geom::pi) / n + offset; + + auto da = geom::direction(a); + auto db = geom::direction(b); + + painter.line(c + da * r1, c + db * r1, s, gfx::black, false); + painter.line(c + da * r2, c + db * r2, s, gfx::black, false); + + if (i % (n / 6) == 0) + painter.line(c + da * r2, c + da * r1, s, gfx::black, true); + } + } + break; + } } void draw_structure(geom::box const & bbox, crossing const &, gfx::painter & painter) @@ -751,7 +939,12 @@ namespace gmtk case card_type::mixer: case card_type::reshaper: case card_type::hue_shifter: - draw_structure(bbox, transformer{card_to_transformer(type).value()}, painter); + { + float animate = 0.f; + // if (type == card_type::reshaper) + // animate = 0.875f; + draw_structure(bbox, transformer{.type = card_to_transformer(type).value(), .animate = animate}, painter); + } break; case card_type::zoomer: draw_grid(bbox, -1.f, painter, true); @@ -781,20 +974,6 @@ namespace gmtk }); } - float animation_factor(float animate) - { - static geom::gradient const g - { - std::pair{0.5f, 0.f}, - geom::easing_type::cubic, - std::pair{0.875f, 1.f}, - geom::easing_type::cubic, - std::pair{1.f, 0.f}, - }; - - return g(animate); - } - void draw(map & map, gfx::painter & painter, float pixel_size) { map.world.apply([&](vertex const & v, crossing const & c) @@ -864,7 +1043,7 @@ namespace gmtk map.world.apply([&](vertex const & v, transformer const & t) { auto box = v.location.bbox(); - box = geom::expand(box, 0.125f * animation_factor(t.animate) * box[0].length()); + // box = geom::expand(box, 0.125f * animation_factor(t.animate) * box[0].length()); draw_structure(box, t, painter); }); @@ -933,7 +1112,7 @@ namespace gmtk case card_type::hue_shifter: return {"Hue shifter", "Shifts the hue of", " input colors"}; case card_type::reshaper: - return {"Reshaper", "Turns circles into squares", " and squares into hexagons"}; + return {"Reshaper", "Turns circles into squares"}; case card_type::crossing: return {"Bridge", "Allows belts to cross", " without merging"}; case card_type::zoomer: