// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkF3DPointSplatUtilsSDF.h"

const char *vtkF3DPointSplatUtilsSDF =
"// This file is intended to be included in the point splat mapper fragment shader\n"
"// It defines signed distance field functions used to represent anisotropic gaussians\n"
"\n"
"// return the signed distance from a point to a circle of given radius\n"
"float sdCircle(vec2 p, float radius)\n"
"{\n"
"  return length(p) - radius;\n"
"}\n"
"\n"
"// return the signed distance from a point to a box of given half size and corner radius\n"
"float sdRoundBox(vec2 p, vec2 halfSize, float radius)\n"
"{\n"
"    vec2 q = abs(p) - halfSize + radius;\n"
"    return length(max(q, 0.0)) - radius + min(max(q.x, q.y), 0.0);\n"
"}\n"
"\n"
"// return the positive distance from a point to a line segment defined by points a and b\n"
"float sdSegment(vec2 p, vec2 a, vec2 b)\n"
"{\n"
"    vec2 pa = p - a;\n"
"    vec2 ba = b - a;\n"
"    float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);\n"
"    return length(pa - ba * h);\n"
"}\n"
"\n"
"// boolean union operation between two SDFs\n"
"float opMerge(float shape1, float shape2)\n"
"{\n"
"    return min(shape1, shape2);\n"
"}\n"
"\n"
"// boolean union operation between two SDFs with smooth blending\n"
"float opRoundMerge(float shape1, float shape2, float radius)\n"
"{\n"
"    vec2 intersectionSpace = vec2(shape1 - radius, shape2 - radius);\n"
"    intersectionSpace = min(intersectionSpace, 0.0);\n"
"    float insideDistance = -length(intersectionSpace);\n"
"    float simpleUnion = opMerge(shape1, shape2);\n"
"    float outsideDistance = max(simpleUnion, radius);\n"
"    return  insideDistance + outsideDistance;\n"
"}\n"
"\n"
"// shift operation to expand or contract an SDF\n"
"float opShift(float sd, float shift)\n"
"{\n"
"  return sd - shift;\n"
"}\n"
"\n"
"// stroke a SDF with given thickness\n"
"// signed distance and thickness is expressed in pixels\n"
"float strokePx(float sd, float thickness)\n"
"{\n"
"  float halfStroke = 0.5 * thickness;\n"
"  return 1.0 - smoothstep(halfStroke - 1.0, halfStroke + 1.0, abs(sd));\n"
"}\n"
"\n"
"// stroke a SDF with given thickness\n"
"// signed distance and thickness is expressed in object space units\n"
"float stroke(float sd, float thickness)\n"
"{\n"
"  float w = fwidth(sd);\n"
"  float halfStroke = 0.5 * thickness * w;\n"
"  return 1.0 - smoothstep(halfStroke - w, halfStroke + w, abs(sd));\n"
"}\n"
"\n"
"// fill a SDF\n"
"// signed distance is expressed in pixels\n"
"float fillPx(float sd)\n"
"{\n"
"    return 1.0 - smoothstep(0.0, 1.0, sd);\n"
"}\n"
"\n"
"// fill a SDF\n"
"// signed distance is expressed in object space units\n"
"float fill(float sd)\n"
"{\n"
"    float w = fwidth(sd);\n"
"    return 1.0 - smoothstep(0.0, w, sd);\n"
"}\n"
"";
