22 #include "src/model.h" |
22 #include "src/model.h" |
23 #include "src/ui/objecteditor.h" |
23 #include "src/ui/objecteditor.h" |
24 #include "src/gl/partrenderer.h" |
24 #include "src/gl/partrenderer.h" |
25 #include "src/circularprimitive.h" |
25 #include "src/circularprimitive.h" |
26 #include "src/layers/edittools.h" |
26 #include "src/layers/edittools.h" |
|
27 #include "src/invert.h" |
27 |
28 |
28 // Make mapbox::earcut work with glm::vec3 |
29 // Make mapbox::earcut work with glm::vec3 |
29 template<> struct mapbox::util::nth<0, glm::vec3> |
30 template<> struct mapbox::util::nth<0, glm::vec3> |
30 { |
31 { |
31 static constexpr float get(const glm::vec3& t) { return t.x; } |
32 static constexpr float get(const glm::vec3& t) { return t.x; } |
434 std::vector<std::vector<glm::vec3>> polygons{1}; |
435 std::vector<std::vector<glm::vec3>> polygons{1}; |
435 std::vector<glm::vec3>& polygon2d = polygons.back(); |
436 std::vector<glm::vec3>& polygon2d = polygons.back(); |
436 polygon2d.reserve(this->numpoints); |
437 polygon2d.reserve(this->numpoints); |
437 for (std::size_t i = 0; i < this->numpoints; ++i) { |
438 for (std::size_t i = 0; i < this->numpoints; ++i) { |
438 polygon2d.push_back(inverseGrid * glm::vec4{this->polygon[i], 1}); |
439 polygon2d.push_back(inverseGrid * glm::vec4{this->polygon[i], 1}); |
439 } |
440 } |
|
441 // mapbox::earcut will always produce a CCW polygon, so if we're drawing |
|
442 // a CW polygon, we should invert the result afterwards |
|
443 const float shouldInvert = glm::dot( |
|
444 glm::vec3{inverseGrid[2]}, |
|
445 glm::cross(this->polygon[0] - this->polygon[1], this->polygon[2] - this->polygon[1])); |
440 using indextype = std::uint16_t; |
446 using indextype = std::uint16_t; |
441 const std::vector<indextype> indices = mapbox::earcut<std::uint16_t>(polygons); |
447 const std::vector<indextype> indices = mapbox::earcut<std::uint16_t>(polygons); |
442 MergedTriangles mergedTriangles = mergeTriangles(indices, this->polygon); |
448 MergedTriangles mergedTriangles = mergeTriangles(indices, this->polygon); |
443 for (const Quadrilateral& quad : mergedTriangles.quadrilaterals) { |
449 for (Quadrilateral& quad : mergedTriangles.quadrilaterals) { |
|
450 if (shouldInvert < 0) { |
|
451 invert(quad); |
|
452 } |
444 result.push_back(AppendToModel{ |
453 result.push_back(AppendToModel{ |
445 .newElement = Colored<Quadrilateral>{quad, MAIN_COLOR}, |
454 .newElement = Colored<Quadrilateral>{quad, MAIN_COLOR}, |
446 }); |
455 }); |
447 } |
456 } |
448 for (std::size_t i = 0; i < indices.size(); i += 3) { |
457 for (std::size_t i = 0; i < indices.size(); i += 3) { |
449 if (mergedTriangles.cutTriangles.find(i) == mergedTriangles.cutTriangles.end()) { |
458 if (mergedTriangles.cutTriangles.find(i) == mergedTriangles.cutTriangles.end()) { |
|
459 Triangle triangle{ |
|
460 Triangle{ |
|
461 .p1 = this->polygon[indices[i]], |
|
462 .p2 = this->polygon[indices[i + 1]], |
|
463 .p3 = this->polygon[indices[i + 2]], |
|
464 } |
|
465 }; |
|
466 if (shouldInvert < 0) { |
|
467 invert(triangle); |
|
468 } |
450 result.push_back(AppendToModel{ |
469 result.push_back(AppendToModel{ |
451 .newElement = Colored<Triangle>{ |
470 .newElement = Colored<Triangle>{ |
452 Triangle{ |
471 triangle, |
453 .p1 = this->polygon[indices[i]], |
|
454 .p2 = this->polygon[indices[i + 1]], |
|
455 .p3 = this->polygon[indices[i + 2]], |
|
456 }, |
|
457 MAIN_COLOR, |
472 MAIN_COLOR, |
458 } |
473 } |
459 }); |
474 }); |
460 } |
475 } |
461 } |
476 } |