mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
96 lines
3.5 KiB
C++
96 lines
3.5 KiB
C++
#include <LottieMesh/LottieMesh.h>
|
|
|
|
#include <LottieMesh/Point.h>
|
|
#include "Triangulation.h"
|
|
|
|
#include "tesselator.h"
|
|
#include "Polyline2D.h"
|
|
|
|
namespace MeshGenerator {
|
|
|
|
std::unique_ptr<Mesh> generateMesh(std::vector<Path> const &paths, std::unique_ptr<Fill> fill, std::unique_ptr<Stroke> stroke) {
|
|
if (stroke) {
|
|
std::unique_ptr<Mesh> mesh = std::make_unique<Mesh>();
|
|
|
|
for (const auto &path : paths) {
|
|
crushedpixel::Polyline2D::JointStyle jointStyle = crushedpixel::Polyline2D::JointStyle::ROUND;
|
|
crushedpixel::Polyline2D::EndCapStyle endCapStyle = crushedpixel::Polyline2D::EndCapStyle::SQUARE;
|
|
switch (stroke->lineJoin) {
|
|
case Stroke::LineJoin::Miter:
|
|
jointStyle = crushedpixel::Polyline2D::JointStyle::MITER;
|
|
break;
|
|
case Stroke::LineJoin::Round:
|
|
jointStyle = crushedpixel::Polyline2D::JointStyle::ROUND;
|
|
break;
|
|
case Stroke::LineJoin::Bevel:
|
|
jointStyle = crushedpixel::Polyline2D::JointStyle::BEVEL;
|
|
break;
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
switch (stroke->lineCap) {
|
|
case Stroke::LineCap::Round: {
|
|
endCapStyle = crushedpixel::Polyline2D::EndCapStyle::ROUND;
|
|
break;
|
|
}
|
|
case Stroke::LineCap::Square: {
|
|
endCapStyle = crushedpixel::Polyline2D::EndCapStyle::SQUARE;
|
|
break;
|
|
}
|
|
case Stroke::LineCap::Butt: {
|
|
endCapStyle = crushedpixel::Polyline2D::EndCapStyle::BUTT;
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto vertices = crushedpixel::Polyline2D::create(path.points, stroke->lineWidth, jointStyle, endCapStyle);
|
|
for (const auto &vertex : vertices) {
|
|
mesh->triangles.push_back((int)mesh->vertices.size());
|
|
mesh->vertices.push_back(vertex);
|
|
}
|
|
}
|
|
|
|
assert(mesh->triangles.size() % 3 == 0);
|
|
return mesh;
|
|
} else if (fill) {
|
|
TESStesselator *tessellator = tessNewTess(NULL);
|
|
tessSetOption(tessellator, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, 1);
|
|
for (const auto &path : paths) {
|
|
tessAddContour(tessellator, 2, path.points.data(), sizeof(Point), (int)path.points.size());
|
|
}
|
|
|
|
switch (fill->rule) {
|
|
case Fill::Rule::EvenOdd: {
|
|
tessTesselate(tessellator, TESS_WINDING_ODD, TESS_POLYGONS, 3, 2, NULL);
|
|
break;
|
|
}
|
|
default: {
|
|
tessTesselate(tessellator, TESS_WINDING_NONZERO, TESS_POLYGONS, 3, 2, NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int vertexCount = tessGetVertexCount(tessellator);
|
|
const TESSreal *vertices = tessGetVertices(tessellator);
|
|
int indexCount = tessGetElementCount(tessellator) * 3;
|
|
const TESSindex *indices = tessGetElements(tessellator);
|
|
|
|
std::unique_ptr<Mesh> mesh = std::make_unique<Mesh>();
|
|
for (int i = 0; i < vertexCount; i++) {
|
|
mesh->vertices.push_back(Point(vertices[i * 2 + 0], vertices[i * 2 + 1]));
|
|
}
|
|
for (int i = 0; i < indexCount; i++) {
|
|
mesh->triangles.push_back(indices[i]);
|
|
}
|
|
return mesh;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
}
|