1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-16 14:00:40 +00:00

msdfgen: Update to 1.12

This commit is contained in:
Rémi Verschelde
2025-01-09 21:16:08 +01:00
parent 24d74510e5
commit c97c7b73e6
41 changed files with 1038 additions and 363 deletions

View File

@@ -6,15 +6,34 @@
namespace msdfgen {
void EdgeSegment::distanceToPseudoDistance(SignedDistance &distance, Point2 origin, double param) const {
EdgeSegment *EdgeSegment::create(Point2 p0, Point2 p1, EdgeColor edgeColor) {
return new LinearSegment(p0, p1, edgeColor);
}
EdgeSegment *EdgeSegment::create(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor) {
if (!crossProduct(p1-p0, p2-p1))
return new LinearSegment(p0, p2, edgeColor);
return new QuadraticSegment(p0, p1, p2, edgeColor);
}
EdgeSegment *EdgeSegment::create(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor) {
Vector2 p12 = p2-p1;
if (!crossProduct(p1-p0, p12) && !crossProduct(p12, p3-p2))
return new LinearSegment(p0, p3, edgeColor);
if ((p12 = 1.5*p1-.5*p0) == 1.5*p2-.5*p3)
return new QuadraticSegment(p0, p12, p3, edgeColor);
return new CubicSegment(p0, p1, p2, p3, edgeColor);
}
void EdgeSegment::distanceToPerpendicularDistance(SignedDistance &distance, Point2 origin, double param) const {
if (param < 0) {
Vector2 dir = direction(0).normalize();
Vector2 aq = origin-point(0);
double ts = dotProduct(aq, dir);
if (ts < 0) {
double pseudoDistance = crossProduct(aq, dir);
if (fabs(pseudoDistance) <= fabs(distance.distance)) {
distance.distance = pseudoDistance;
double perpendicularDistance = crossProduct(aq, dir);
if (fabs(perpendicularDistance) <= fabs(distance.distance)) {
distance.distance = perpendicularDistance;
distance.dot = 0;
}
}
@@ -23,9 +42,9 @@ void EdgeSegment::distanceToPseudoDistance(SignedDistance &distance, Point2 orig
Vector2 bq = origin-point(1);
double ts = dotProduct(bq, dir);
if (ts > 0) {
double pseudoDistance = crossProduct(bq, dir);
if (fabs(pseudoDistance) <= fabs(distance.distance)) {
distance.distance = pseudoDistance;
double perpendicularDistance = crossProduct(bq, dir);
if (fabs(perpendicularDistance) <= fabs(distance.distance)) {
distance.distance = perpendicularDistance;
distance.dot = 0;
}
}
@@ -38,18 +57,12 @@ LinearSegment::LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor) : EdgeSe
}
QuadraticSegment::QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor) : EdgeSegment(edgeColor) {
if (p1 == p0 || p1 == p2)
p1 = 0.5*(p0+p2);
p[0] = p0;
p[1] = p1;
p[2] = p2;
}
CubicSegment::CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor) : EdgeSegment(edgeColor) {
if ((p1 == p0 || p1 == p3) && (p2 == p0 || p2 == p3)) {
p1 = mix(p0, p3, 1/3.);
p2 = mix(p0, p3, 2/3.);
}
p[0] = p0;
p[1] = p1;
p[2] = p2;
@@ -486,43 +499,29 @@ void CubicSegment::moveEndPoint(Point2 to) {
p[3] = to;
}
void LinearSegment::splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const {
part1 = new LinearSegment(p[0], point(1/3.), color);
part2 = new LinearSegment(point(1/3.), point(2/3.), color);
part3 = new LinearSegment(point(2/3.), p[1], color);
void LinearSegment::splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const {
part0 = new LinearSegment(p[0], point(1/3.), color);
part1 = new LinearSegment(point(1/3.), point(2/3.), color);
part2 = new LinearSegment(point(2/3.), p[1], color);
}
void QuadraticSegment::splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const {
part1 = new QuadraticSegment(p[0], mix(p[0], p[1], 1/3.), point(1/3.), color);
part2 = new QuadraticSegment(point(1/3.), mix(mix(p[0], p[1], 5/9.), mix(p[1], p[2], 4/9.), .5), point(2/3.), color);
part3 = new QuadraticSegment(point(2/3.), mix(p[1], p[2], 2/3.), p[2], color);
void QuadraticSegment::splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const {
part0 = new QuadraticSegment(p[0], mix(p[0], p[1], 1/3.), point(1/3.), color);
part1 = new QuadraticSegment(point(1/3.), mix(mix(p[0], p[1], 5/9.), mix(p[1], p[2], 4/9.), .5), point(2/3.), color);
part2 = new QuadraticSegment(point(2/3.), mix(p[1], p[2], 2/3.), p[2], color);
}
void CubicSegment::splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const {
part1 = new CubicSegment(p[0], p[0] == p[1] ? p[0] : mix(p[0], p[1], 1/3.), mix(mix(p[0], p[1], 1/3.), mix(p[1], p[2], 1/3.), 1/3.), point(1/3.), color);
part2 = new CubicSegment(point(1/3.),
void CubicSegment::splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const {
part0 = new CubicSegment(p[0], p[0] == p[1] ? p[0] : mix(p[0], p[1], 1/3.), mix(mix(p[0], p[1], 1/3.), mix(p[1], p[2], 1/3.), 1/3.), point(1/3.), color);
part1 = new CubicSegment(point(1/3.),
mix(mix(mix(p[0], p[1], 1/3.), mix(p[1], p[2], 1/3.), 1/3.), mix(mix(p[1], p[2], 1/3.), mix(p[2], p[3], 1/3.), 1/3.), 2/3.),
mix(mix(mix(p[0], p[1], 2/3.), mix(p[1], p[2], 2/3.), 2/3.), mix(mix(p[1], p[2], 2/3.), mix(p[2], p[3], 2/3.), 2/3.), 1/3.),
point(2/3.), color);
part3 = new CubicSegment(point(2/3.), mix(mix(p[1], p[2], 2/3.), mix(p[2], p[3], 2/3.), 2/3.), p[2] == p[3] ? p[3] : mix(p[2], p[3], 2/3.), p[3], color);
part2 = new CubicSegment(point(2/3.), mix(mix(p[1], p[2], 2/3.), mix(p[2], p[3], 2/3.), 2/3.), p[2] == p[3] ? p[3] : mix(p[2], p[3], 2/3.), p[3], color);
}
EdgeSegment *QuadraticSegment::convertToCubic() const {
return new CubicSegment(p[0], mix(p[0], p[1], 2/3.), mix(p[1], p[2], 1/3.), p[2], color);
}
void CubicSegment::deconverge(int param, double amount) {
Vector2 dir = direction(param);
Vector2 normal = dir.getOrthonormal();
double h = dotProduct(directionChange(param)-dir, normal);
switch (param) {
case 0:
p[1] += amount*(dir+sign(h)*sqrt(fabs(h))*normal);
break;
case 1:
p[2] -= amount*(dir-sign(h)*sqrt(fabs(h))*normal);
break;
}
}
}