1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +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

@@ -13,45 +13,45 @@ class DistancePixelConversion;
template <>
class DistancePixelConversion<double> {
double invRange;
DistanceMapping mapping;
public:
typedef BitmapRef<float, 1> BitmapRefType;
inline explicit DistancePixelConversion(double range) : invRange(1/range) { }
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
inline void operator()(float *pixels, double distance) const {
*pixels = float(invRange*distance+.5);
*pixels = float(mapping(distance));
}
};
template <>
class DistancePixelConversion<MultiDistance> {
double invRange;
DistanceMapping mapping;
public:
typedef BitmapRef<float, 3> BitmapRefType;
inline explicit DistancePixelConversion(double range) : invRange(1/range) { }
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
inline void operator()(float *pixels, const MultiDistance &distance) const {
pixels[0] = float(invRange*distance.r+.5);
pixels[1] = float(invRange*distance.g+.5);
pixels[2] = float(invRange*distance.b+.5);
pixels[0] = float(mapping(distance.r));
pixels[1] = float(mapping(distance.g));
pixels[2] = float(mapping(distance.b));
}
};
template <>
class DistancePixelConversion<MultiAndTrueDistance> {
double invRange;
DistanceMapping mapping;
public:
typedef BitmapRef<float, 4> BitmapRefType;
inline explicit DistancePixelConversion(double range) : invRange(1/range) { }
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
inline void operator()(float *pixels, const MultiAndTrueDistance &distance) const {
pixels[0] = float(invRange*distance.r+.5);
pixels[1] = float(invRange*distance.g+.5);
pixels[2] = float(invRange*distance.b+.5);
pixels[3] = float(invRange*distance.a+.5);
pixels[0] = float(mapping(distance.r));
pixels[1] = float(mapping(distance.g));
pixels[2] = float(mapping(distance.b));
pixels[3] = float(mapping(distance.a));
}
};
template <class ContourCombiner>
void generateDistanceField(const typename DistancePixelConversion<typename ContourCombiner::DistanceType>::BitmapRefType &output, const Shape &shape, const Projection &projection, double range) {
DistancePixelConversion<typename ContourCombiner::DistanceType> distancePixelConversion(range);
void generateDistanceField(const typename DistancePixelConversion<typename ContourCombiner::DistanceType>::BitmapRefType &output, const Shape &shape, const SDFTransformation &transformation) {
DistancePixelConversion<typename ContourCombiner::DistanceType> distancePixelConversion(transformation.distanceMapping);
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel
#endif
@@ -65,7 +65,7 @@ void generateDistanceField(const typename DistancePixelConversion<typename Conto
int row = shape.inverseYAxis ? output.height-y-1 : y;
for (int col = 0; col < output.width; ++col) {
int x = rightToLeft ? output.width-col-1 : col;
Point2 p = projection.unproject(Point2(x+.5, y+.5));
Point2 p = transformation.unproject(Point2(x+.5, y+.5));
typename ContourCombiner::DistanceType distance = distanceFinder.distance(p);
distancePixelConversion(output(x, row), distance);
}
@@ -74,57 +74,96 @@ void generateDistanceField(const typename DistancePixelConversion<typename Conto
}
}
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, double range, const GeneratorConfig &config) {
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, projection, range);
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
else
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, projection, range);
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
}
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, double range, const GeneratorConfig &config) {
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<PseudoDistanceSelector> >(output, shape, projection, range);
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
else
generateDistanceField<SimpleContourCombiner<PseudoDistanceSelector> >(output, shape, projection, range);
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
}
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const Projection &projection, double range, const MSDFGeneratorConfig &config) {
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, projection, range);
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, transformation);
else
generateDistanceField<SimpleContourCombiner<MultiDistanceSelector> >(output, shape, projection, range);
msdfErrorCorrection(output, shape, projection, range, config);
generateDistanceField<SimpleContourCombiner<MultiDistanceSelector> >(output, shape, transformation);
msdfErrorCorrection(output, shape, transformation, config);
}
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const Projection &projection, double range, const MSDFGeneratorConfig &config) {
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, projection, range);
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, transformation);
else
generateDistanceField<SimpleContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, projection, range);
msdfErrorCorrection(output, shape, projection, range, config);
generateDistanceField<SimpleContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, transformation);
msdfErrorCorrection(output, shape, transformation, config);
}
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
else
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
}
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
else
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
}
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, SDFTransformation(projection, range));
else
generateDistanceField<SimpleContourCombiner<MultiDistanceSelector> >(output, shape, SDFTransformation(projection, range));
msdfErrorCorrection(output, shape, SDFTransformation(projection, range), config);
}
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
if (config.overlapSupport)
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
else
generateDistanceField<SimpleContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
msdfErrorCorrection(output, shape, SDFTransformation(projection, range), config);
}
// Legacy API
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
generatePSDF(output, shape, SDFTransformation(projection, range), config);
}
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
generateSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
}
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
generatePseudoSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
}
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
}
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
generateMSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
}
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
generateMTSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
}
// Legacy version
void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate) {
void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
DistanceMapping distanceMapping(range);
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel for
#endif
@@ -140,12 +179,13 @@ void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, d
if (distance < minDistance)
minDistance = distance;
}
*output(x, row) = float(minDistance.distance/range+.5);
*output(x, row) = float(distanceMapping(minDistance.distance));
}
}
}
void generatePseudoSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate) {
void generatePSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
DistanceMapping distanceMapping(range);
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel for
#endif
@@ -167,13 +207,18 @@ void generatePseudoSDF_legacy(const BitmapRef<float, 1> &output, const Shape &sh
}
}
if (nearEdge)
(*nearEdge)->distanceToPseudoDistance(minDistance, p, nearParam);
*output(x, row) = float(minDistance.distance/range+.5);
(*nearEdge)->distanceToPerpendicularDistance(minDistance, p, nearParam);
*output(x, row) = float(distanceMapping(minDistance.distance));
}
}
}
void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
void generatePseudoSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
generatePSDF_legacy(output, shape, range, scale, translate);
}
void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
DistanceMapping distanceMapping(range);
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel for
#endif
@@ -212,14 +257,14 @@ void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape,
}
if (r.nearEdge)
(*r.nearEdge)->distanceToPseudoDistance(r.minDistance, p, r.nearParam);
(*r.nearEdge)->distanceToPerpendicularDistance(r.minDistance, p, r.nearParam);
if (g.nearEdge)
(*g.nearEdge)->distanceToPseudoDistance(g.minDistance, p, g.nearParam);
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
if (b.nearEdge)
(*b.nearEdge)->distanceToPseudoDistance(b.minDistance, p, b.nearParam);
output(x, row)[0] = float(r.minDistance.distance/range+.5);
output(x, row)[1] = float(g.minDistance.distance/range+.5);
output(x, row)[2] = float(b.minDistance.distance/range+.5);
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
output(x, row)[0] = float(distanceMapping(r.minDistance.distance));
output(x, row)[1] = float(distanceMapping(g.minDistance.distance));
output(x, row)[2] = float(distanceMapping(b.minDistance.distance));
}
}
@@ -227,7 +272,8 @@ void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape,
msdfErrorCorrection(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(false, errorCorrectionConfig));
}
void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape, double range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
DistanceMapping distanceMapping(range);
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel for
#endif
@@ -269,15 +315,15 @@ void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape,
}
if (r.nearEdge)
(*r.nearEdge)->distanceToPseudoDistance(r.minDistance, p, r.nearParam);
(*r.nearEdge)->distanceToPerpendicularDistance(r.minDistance, p, r.nearParam);
if (g.nearEdge)
(*g.nearEdge)->distanceToPseudoDistance(g.minDistance, p, g.nearParam);
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
if (b.nearEdge)
(*b.nearEdge)->distanceToPseudoDistance(b.minDistance, p, b.nearParam);
output(x, row)[0] = float(r.minDistance.distance/range+.5);
output(x, row)[1] = float(g.minDistance.distance/range+.5);
output(x, row)[2] = float(b.minDistance.distance/range+.5);
output(x, row)[3] = float(minDistance.distance/range+.5);
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
output(x, row)[0] = float(distanceMapping(r.minDistance.distance));
output(x, row)[1] = float(distanceMapping(g.minDistance.distance));
output(x, row)[2] = float(distanceMapping(b.minDistance.distance));
output(x, row)[3] = float(distanceMapping(minDistance.distance));
}
}