src/circularprimitive.h

changeset 379
8d88adffb779
parent 305
d891da20abca
equal deleted inserted replaced
378:01537fbe096e 379:8d88adffb779
3 #include "src/basics.h" 3 #include "src/basics.h"
4 #include "src/model.h" 4 #include "src/model.h"
5 #include "src/ldrawalgorithm.h" 5 #include "src/ldrawalgorithm.h"
6 6
7 template<typename Fn> 7 template<typename Fn>
8 void rasterize(const CircularPrimitive& circ, Fn&& fn) 8 void circular_element_to_polygons(const circular_primitive& circ, Fn&& fn)
9 { 9 {
10 std::vector<ModelElement> result; 10 std::vector<ModelElement> result;
11 const auto xform = [&circ](const glm::vec2& p, float y){ 11 const auto xform = [&circ](const glm::vec2& p, float y){
12 return glm::vec3{circ.transformation * glm::vec4{p.x, y, p.y, 1}}; 12 return glm::vec3{circ.transformation * glm::vec4{p.x, y, p.y, 1}};
13 }; 13 };
14 const glm::vec3 primitiveOrigin = xform({0, 0}, 0); 14 const glm::vec3 primitiveOrigin = xform({0, 0}, 0);
15 const bool invertedMatrix = (glm::determinant(circ.transformation) < 0) != circ.inverted; 15 const bool invertedMatrix = (glm::determinant(circ.transformation) < 0) != circ.inverted;
16 switch(circ.type) { 16 switch(circ.type) {
17 case CircularPrimitive::Circle: 17 case circular_primitive_type_e::circle:
18 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&] 18 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
19 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){ 19 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
20 fn(LineSegment{xform(p1, 0), xform(p2, 0)}, EDGE_COLOR); 20 fn(LineSegment{xform(p1, 0), xform(p2, 0)}, EDGE_COLOR);
21 }); 21 });
22 break; 22 break;
23 case CircularPrimitive::Disc: 23 case circular_primitive_type_e::disc:
24 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&] 24 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
25 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){ 25 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
26 fn(Triangle{primitiveOrigin, xform(p1, 0), xform(p2, 0)}, MAIN_COLOR); 26 fn(Triangle{primitiveOrigin, xform(p1, 0), xform(p2, 0)}, MAIN_COLOR);
27 }); 27 });
28 break; 28 break;
29 case CircularPrimitive::Cylinder: 29 case circular_primitive_type_e::cylinder:
30 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&] 30 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
31 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){ 31 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
32 Quadrilateral quad{xform(p1, 1), xform(p2, 1), xform(p2, 0), xform(p1, 0)}; 32 Quadrilateral quad{xform(p1, 1), xform(p2, 1), xform(p2, 0), xform(p1, 0)};
33 if (invertedMatrix) { 33 if (invertedMatrix) {
34 std::swap(quad.p2, quad.p4); 34 std::swap(quad.p2, quad.p4);
35 } 35 }
36 fn(quad, MAIN_COLOR); 36 fn(quad, MAIN_COLOR);
37 }); 37 });
38 break; 38 break;
39 case CircularPrimitive::CylinderOpen: 39 case circular_primitive_type_e::cylinder_open:
40 rasterize(CircularPrimitive{ 40 circular_element_to_polygons(circular_primitive{
41 .type = CircularPrimitive::Cylinder, 41 .type = circular_primitive_type_e::cylinder,
42 .fraction = circ.fraction, 42 .fraction = circ.fraction,
43 .transformation = circ.transformation, 43 .transformation = circ.transformation,
44 }, fn); 44 }, fn);
45 rasterize(CircularPrimitive{ 45 circular_element_to_polygons(circular_primitive{
46 .type = CircularPrimitive::Circle, 46 .type = circular_primitive_type_e::circle,
47 .fraction = circ.fraction, 47 .fraction = circ.fraction,
48 .transformation = circ.transformation, 48 .transformation = circ.transformation,
49 }, fn); 49 }, fn);
50 rasterize(CircularPrimitive{ 50 circular_element_to_polygons(circular_primitive{
51 .type = CircularPrimitive::Circle, 51 .type = circular_primitive_type_e::circle,
52 .fraction = circ.fraction, 52 .fraction = circ.fraction,
53 .transformation = glm::translate(circ.transformation, {0, 1, 0}), 53 .transformation = glm::translate(circ.transformation, {0, 1, 0}),
54 }, fn); 54 }, fn);
55 break; 55 break;
56 case CircularPrimitive::CylinderClosed: 56 case circular_primitive_type_e::cylinder_closed:
57 rasterize(CircularPrimitive{ 57 circular_element_to_polygons(circular_primitive{
58 .type = CircularPrimitive::CylinderOpen, 58 .type = circular_primitive_type_e::cylinder_open,
59 .fraction = circ.fraction, 59 .fraction = circ.fraction,
60 .transformation = circ.transformation, 60 .transformation = circ.transformation,
61 }, fn); 61 }, fn);
62 rasterize(CircularPrimitive{ 62 circular_element_to_polygons(circular_primitive{
63 .type = CircularPrimitive::Disc, 63 .type = circular_primitive_type_e::disc,
64 .fraction = circ.fraction, 64 .fraction = circ.fraction,
65 .transformation = circ.transformation, 65 .transformation = circ.transformation,
66 }, fn); 66 }, fn);
67 break; 67 break;
68 case CircularPrimitive::DiscNegative: 68 case circular_primitive_type_e::disc_negative:
69 { 69 {
70 unsigned int i = 0; 70 unsigned int i = 0;
71 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&] 71 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
72 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){ 72 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
73 constexpr glm::vec2 corners[4] = { 73 constexpr glm::vec2 corners[4] = {
80 fn(Triangle{xform(p2, 0), xform(p1, 0), xform(corner, 0)}, MAIN_COLOR); 80 fn(Triangle{xform(p2, 0), xform(p1, 0), xform(corner, 0)}, MAIN_COLOR);
81 ++i; 81 ++i;
82 }); 82 });
83 } 83 }
84 break; 84 break;
85 case CircularPrimitive::Chord: 85 case circular_primitive_type_e::chord:
86 for (unsigned int i = 1; i < circ.fraction.segments; ++i) { 86 for (unsigned int i = 1; i < circ.fraction.segments; ++i) {
87 const glm::vec2& p1 = ldraw::rimpoint(circ.fraction.divisions, i); 87 const glm::vec2& p1 = ldraw::rimpoint(circ.fraction.divisions, i);
88 const glm::vec2& p2 = ldraw::rimpoint(circ.fraction.divisions, i + 1); 88 const glm::vec2& p2 = ldraw::rimpoint(circ.fraction.divisions, i + 1);
89 fn(Triangle{xform(p2, 0), xform(p1, 0), xform({1, 0}, 0)}, MAIN_COLOR); 89 fn(Triangle{xform(p2, 0), xform(p1, 0), xform({1, 0}, 0)}, MAIN_COLOR);
90 } 90 }

mercurial