#include <helper_math.h>
#define M_PI 3.1415926535
#define PI_2 (M_PI * 2.0)
struct AddIn {
float value1;
float value2;
};
struct AddOut {
float value;
};
__device__ __forceinline__ AddOut AddImpl(AddIn input_) {
return AddOut{input_.value1 + input_.value2};
}
struct Add2fIn {
float2 value1;
float2 value2;
};
struct Add2fOut {
float2 value;
};
__device__ __forceinline__ Add2fOut Add2fImpl(Add2fIn input_) {
return Add2fOut{float2{input_.value1.x + input_.value2.x, input_.value1.y + input_.value2.y}};
}
struct MulIn {
float value1;
float value2;
};
struct MulOut {
float value;
};
__device__ __forceinline__ MulOut MulImpl(MulIn input_) {
return MulOut{input_.value1 * input_.value2};
}
struct Mul2fIn {
float2 value1;
float2 value2;
};
struct Mul2fOut {
float2 value;
};
__device__ __forceinline__ Mul2fOut Mul2fImpl(Mul2fIn input_) {
return Mul2fOut{float2{input_.value1.x * input_.value2.x, input_.value1.y * input_.value2.y}};
}
struct DivIn {
float value1;
float value2;
};
struct DivOut {
float value;
};
__device__ __forceinline__ DivOut DivImpl(DivIn input_) {
return DivOut{input_.value1 / input_.value2};
}
struct Div2fIn {
float2 value1;
float2 value2;
};
struct Div2fOut {
float2 value;
};
__device__ __forceinline__ Div2fOut Div2fImpl(Div2fIn input_) {
return Div2fOut{float2{input_.value1.x / input_.value2.x, input_.value1.y / input_.value2.y}};
}
struct SubIn {
float value1;
float value2;
};
struct SubOut {
float value;
};
__device__ __forceinline__ SubOut SubImpl(SubIn input_) {
return SubOut{input_.value1 - input_.value2};
}
struct Sub2fIn {
float2 value1;
float2 value2;
};
struct Sub2fOut {
float2 value;
};
__device__ __forceinline__ Sub2fOut Sub2fImpl(Sub2fIn input_) {
return Sub2fOut{float2{input_.value1.x - input_.value2.x, input_.value1.y - input_.value2.y}};
}
struct NormalizeIn {
float value1;
float value2;
float value3;
};
struct NormalizeOut {
float value;
};
__device__ __forceinline__ NormalizeOut NormalizeImpl(NormalizeIn input_) {
return NormalizeOut{input_.value1 * input_.value2 - input_.value3};
}
struct Normalize2fIn {
float2 value1;
float2 value2;
float2 value3;
};
struct Normalize2fOut {
float2 value;
};
__device__ __forceinline__ Normalize2fOut Normalize2fImpl(Normalize2fIn input_) {
return Normalize2fOut{float2{input_.value1.x * input_.value2.x - input_.value3.x, input_.value1.y * input_.value2.y - input_.value3.y}};
}
struct NegIn {
float x;
};
struct NegOut {
float value;
};
__device__ __forceinline__ NegOut NegImpl(NegIn input_) {
return NegOut{-input_.x};
}
struct ToVec2In {
float x;
float y;
};
struct ToVec2Out {
float2 value;
};
__device__ __forceinline__ ToVec2Out ToVec2Impl(ToVec2In input_) {
return ToVec2Out{float2{input_.x, input_.y}};
}
struct FromVec2In {
float2 value;
};
struct FromVec2Out {
float x;
float y;
};
__device__ __forceinline__ FromVec2Out FromVec2Impl(FromVec2In input_) {
return FromVec2Out{input_.value.x, input_.value.y};
}
struct RoundIn {
float value;
};
struct RoundOut {
float value;
};
__device__ __forceinline__ RoundOut RoundImpl(RoundIn input_) {
return RoundOut{round(input_.value)};
}
struct CircleIn {
float2 position;
float radius;
float inner;
};
struct CircleOut {
float distance;
};
__device__ __forceinline__ CircleOut CircleImpl(CircleIn input_) {
float2 p = input_.position;
float inner = input_.inner > input_.radius * 0.1 ? 1.0 : input_.inner;
float circle = sqrt(length(p)) - input_.radius;
return CircleOut{abs(circle + input_.inner) - input_.inner};
}
struct BoxIn {
float2 position;
float radius;
};
struct BoxOut {
float distance;
};
__device__ __forceinline__ BoxOut BoxImpl(BoxIn input_) {
float2 p = input_.position;
float radius = input_.radius;
return BoxOut{abs(p.x) + abs(p.y) - radius};
}
struct JointIn {
float2 position;
float len;
float curvature;
float thickness;
};
struct JointOut {
float distance;
};
__device__ __forceinline__ JointOut JointImpl(JointIn input_) {
float2 p = float2{input_.position.y, input_.position.x};
float len = input_.len;
float curvature = input_.curvature;
float thickness = input_.thickness;
if (abs(curvature) < 0.001) {
p.y -= clamp(p.y, 0.0 , len);
return JointOut{length(p)};
}
float2 sc = make_float2(sin(curvature), cos(curvature));
float ra = 0.5 * len / curvature;
p.x -= ra;
float2 q = p - 2.0 * sc * max(0.0, dot(sc, p));
float d = (q.y < 0.0) ? length(q + make_float2(ra, 0.0)) : abs(abs(ra) - length(q));
return JointOut{d - thickness};
}
struct StripeIn {
float2 position;
float thickness;
};
struct StripeOut {
float distance;
};
__device__ __forceinline__ StripeOut StripeImpl(StripeIn input_) {
float2 p = input_.position;
float sdfStripeY = abs(p.y) - input_.thickness;
return StripeOut{sdfStripeY};
}
struct TriangleWaveIn {
float2 position;
float frequence;
float amplitude;
float thickness;
};
struct TriangleWaveOut {
float distance;
};
__device__ __forceinline__ float TriangleWaveMod(float a, float b) {
int fl = static_cast<int>(floor(a / b));
return a - static_cast<float>(fl) * b;
}
__device__ __forceinline__ TriangleWaveOut TriangleWaveImpl(TriangleWaveIn input_) {
float2 p = input_.position;
float frequence = input_.frequence;
float amplitude = input_.amplitude;
float thickness = input_.thickness;
float pw = 2.0 / frequence;
float qw = 0.25 * pw;
float2 sc = make_float2(4.0 * amplitude, pw);
float l = length(sc);
float posX = abs(TriangleWaveMod(p.x + qw, pw) - 0.5 * pw) - qw;
float posX1 = (posX * sc.x + p.y * sc.y) / l;
float posY = (-posX * sc.y + p.y * sc.x) / l;
float2 pos = make_float2(posX1, max(0.0, abs(posY) - 0.25 * l));
return TriangleWaveOut{length(pos) - thickness};
}
struct SineWaveIn {
float2 position;
float frequence;
float amplitude;
float thickness;
};
struct SineWaveOut {
float distance;
};
__device__ __forceinline__ float SineWaveMod(float a, float b) {
int fl = int(floor(a / b));
return a - float(fl) * b;
}
__device__ __forceinline__ float Sign(float a) {
return a > 0.0 ? 1.0 : (a < 0.0 ? -1.0 : 0.0);
}
__device__ __forceinline__ SineWaveOut SineWaveImpl(SineWaveIn input_) {
float2 p = input_.position;
float frequence = input_.frequence;
float amplitude = input_.amplitude;
float thickness = input_.thickness;
float f = frequence * M_PI * amplitude;
float px = p.x / amplitude;
float py = p.y / amplitude;
float r = M_PI / f;
float h = 0.5 * r;
float ff = f * f;
float2 pos = make_float2(SineWaveMod(px + h, r) - h, py * Sign(r - SineWaveMod(px + h, 2.0 * r)));
float t = fminf(fmaxf((0.818309886184 * f * pos.y + pos.x) / (0.669631069826 * ff + 1.0), -h), h);
for (int n = 0; n < 3; n++) {
float k = t * f;
float c = cosf(k);
float s = sinf(k);
t -= ((s - pos.y) * c * f + t - pos.x) / ((c * c - s * s + s * pos.y) * ff + 1.0);
}
float sine_wave = sqrtf((pos.x - t) * (pos.x - t) + (sinf(t * f) - pos.y) * (sinf(t * f) - pos.y)) * amplitude;
return SineWaveOut{abs(sine_wave) - thickness};
}
struct InterpolationIn {
float distance1;
float distance2;
float interpolation;
};
struct InterpolationOut {
float distance;
};
__device__ __forceinline__ InterpolationOut InterpolationImpl(InterpolationIn input_) {
return InterpolationOut{input_.distance1 + input_.interpolation * (input_.distance2 - input_.distance1)};
}
struct GridIn {
float2 position;
float thickness;
};
struct GridOut {
float distance;
};
__device__ __forceinline__ GridOut GridImpl(GridIn input_) {
float2 p = input_.position;
float sdfStripeX = abs(p.x) - input_.thickness;
float sdfStripeY = abs(p.y) - input_.thickness;
return GridOut{min(sdfStripeX, sdfStripeY)};
}
struct HoneycombGridIn {
float2 position;
float thickness;
};
struct HoneycombGridOut {
float distance;
};
__device__ __forceinline__ float Fract(float x) {
return x - floor(x);
}
__device__ __forceinline__ HoneycombGridOut HoneycombGridImpl(HoneycombGridIn input_) {
float2 p = input_.position;
float py = p.y / 1.7320508076 - 0.5;
float px = p.x / 2.0 - Fract(floor(py) * 0.5);
float px_ = abs(Fract(px) - 0.5);
float py_ = abs(Fract(py) - 0.5);
float sdf = abs(1.0 - max(px_ + py_ * 1.5, px_ * 2.0));
return HoneycombGridOut{sdf - input_.thickness};
}
struct RadialRepetitionIn {
float2 position;
float theta;
float angle;
float distance;
};
struct RadialRepetitionOut {
float2 position1;
float2 position2;
};
__device__ __forceinline__ RadialRepetitionOut RadialRepetitionImpl(RadialRepetitionIn input_) {
float2 position = input_.position;
float angle = input_.angle;
float theta = input_.theta;
float distance = input_.distance;
float a = atan2(position.y, position.x);
float i = theta + floor(a / angle);
float c1 = angle * (i + 0.0);
float p1X = position.x * cos(c1) + position.y * sin(c1);
float p1Y = position.y * cos(c1) - position.x * sin(c1);
float c2 = angle * (i + 1.0);
float p2X = position.x * cos(c2) + position.y * sin(c2);
float p2Y = position.y * cos(c2) - position.x * sin(c2);
float p1XTra = p1X - distance;
float p2XTra = p2X - distance;
return RadialRepetitionOut{float2{p1XTra, p1Y}, float2{p2XTra, p2Y}};
}
struct RadialLineIn {
float2 position;
float theta;
float angle;
float thickness;
};
struct RadialLineOut {
float distance;
};
__device__ __forceinline__ float RadialLineDist(float2 position, float2 ba_, float r) {
float2 pa = position - ba_ * r;
float2 ba = ba_ * r * -2.0;
return length(pa - ba * clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0));
}
__device__ __forceinline__ RadialLineOut RadialLineImpl(RadialLineIn input_) {
float2 position = input_.position;
float theta = input_.theta;
float angle = input_.angle;
float thickness = input_.thickness;
float r = length(position);
float alpha = atan2(position.y, position.x);
float edge = round(alpha / angle);
float step = (theta + edge) * angle;
float2 end = float2{cos(step), sin(step)};
float line = RadialLineDist(position, end, 3.0);
return RadialLineOut{abs(line) - thickness};
}
struct TruchetIn {
float2 position;
float thickness;
float rotation;
};
struct TruchetOut {
float distance;
};
__device__ __forceinline__ TruchetOut TruchetImpl(TruchetIn input_) {
float2 p = input_.position;
float2 ip = floorf(p);
p -= ip + 0.5;
p.y *= (Fract(sin(dot(ip, make_float2(141.213, 289.867))) * 43758.5453 + input_.rotation) > 0.5) ? 1.0 : -1.0;
p *= Sign(p.x + p.y);
p -= 0.5;
float d = length(p) - 0.5;
d = abs(d) - input_.thickness / 2.0;
return TruchetOut{d};
}
struct RotationIn {
float2 position;
float angle;
};
struct RotationOut {
float2 position;
};
__device__ __forceinline__ RotationOut RotationImpl(RotationIn input_) {
float2 p = input_.position;
float theta = input_.angle;
float xRot = p.x * cos(theta) + p.y * sin(theta);
float yRot = p.y * cos(theta) - p.x * sin(theta);
return RotationOut{float2{xRot, yRot}};
}
struct TranslationIn {
float2 position;
float2 translation;
};
struct TranslationOut {
float2 position;
};
__device__ __forceinline__ TranslationOut TranslationImpl(TranslationIn input_) {
float2 p = input_.position;
float2 translation = input_.translation;
return TranslationOut{p - translation};
}
struct ScaleIn {
float2 position;
float scale;
};
struct ScaleOut {
float2 position;
};
__device__ __forceinline__ ScaleOut ScaleImpl(ScaleIn input_) {
float2 p = input_.position;
float scale = input_.scale;
return ScaleOut{p / scale};
}
struct RepetitionIn {
float2 position;
float2 space;
};
struct RepetitionOut {
float2 position;
};
__device__ __forceinline__ float RepetitionMod(float a, float b) {
int fl = int(floor(a / b));
return a - float(fl) * b;
}
__device__ __forceinline__ RepetitionOut RepetitionImpl(RepetitionIn input_) {
float2 p = input_.position;
float2 space = input_.space;
float repPosX = RepetitionMod((p.x + space.x/2.0), space.x) - space.x / 2.0;
float repPosY = RepetitionMod((p.y + space.y/2.0), space.y) - space.y / 2.0;
return RepetitionOut{float2{repPosX, repPosY}};
}
struct Combine2In {
float2 value1;
float2 scale1;
float2 offset1;
float2 value2;
float2 scale2;
float2 offset2;
};
struct Combine2Out {
float2 value;
};
__device__ __forceinline__ Combine2Out Combine2Impl(Combine2In input_) {
return Combine2Out{input_.value1 * input_.scale1 + input_.offset1 +
input_.value2 * input_.scale2 + input_.offset2};
}
struct CircleOnionIn {
float2 position;
float radius;
float inner;
float step;
};
struct CircleOnionOut {
float distance;
};
__device__ __forceinline__ CircleOnionOut CircleOnionImpl(CircleOnionIn input_) {
float2 p = input_.position;
float radius = input_.radius;
float inner = input_.inner > input_.radius * 0.1 ? 1.0 : input_.inner;
float step = max(0.2, input_.step);
float circle = sqrt(length(p)) - radius;
float distance = abs(circle + inner) - inner;
float r = radius - step * radius;
while (r > 0.025) {
float sdf_circle = sqrt(length(p)) - r;
float i = inner > r * 0.1 ? 1.0 : inner;
float sdf_circle_inner = abs(sdf_circle + i) - i;
distance = min(distance, sdf_circle_inner);
r = r - step * radius;
}
return CircleOnionOut{distance};
}
struct OverIn {
float distance1;
float3 color1;
float distance2;
float3 color2;
};
struct OverOut {
float distance;
float3 color;
};
#define OVER_THICKNESS 0.0025
__device__ __forceinline__ float OverBorderSdf(float sdf) {
return abs(sdf + OVER_THICKNESS) - OVER_THICKNESS;
}
__device__ __forceinline__ float OverInnerSdf(float sdf) {
return sdf - OVER_THICKNESS;
}
__device__ __forceinline__ OverOut OverImpl(OverIn input_) {
float distance1 = max(input_.distance1, -OverBorderSdf(input_.distance2));
float distance2 = OverInnerSdf(input_.distance2);
if (distance1 < distance2) {
return OverOut{distance1, input_.color1};
} else {
return OverOut{distance2, input_.color2};
}
}
struct OverIdIn {
float distance1;
float levelid1;
float distance2;
float levelid2;
};
struct OverIdOut {
float distance;
float levelid;
};
#define OVERID_THICKNESS 0.0025
__device__ __forceinline__ float OverIdBorderSdf(float sdf) {
return abs(sdf + OVERID_THICKNESS) - OVERID_THICKNESS;
}
__device__ __forceinline__ float OverIdInnerSdf(float sdf) {
return sdf - OVERID_THICKNESS;
}
__device__ __forceinline__ OverIdOut OverIdImpl(OverIdIn input_) {
float distance1 = max(input_.distance1, -OverIdBorderSdf(input_.distance2));
float distance2 = OverIdInnerSdf(input_.distance2);
if (distance1 < distance2) {
return OverIdOut{distance1, input_.levelid1};
} else {
return OverIdOut{distance2, input_.levelid2};
}
}
struct UnionIdIn {
float distance1;
float levelid1;
float distance2;
float levelid2;
};
struct UnionIdOut {
float distance;
float levelid;
};
__device__ __forceinline__ UnionIdOut UnionIdImpl(UnionIdIn input_) {
if (input_.distance1 < input_.distance2) {
return UnionIdOut{input_.distance1, input_.levelid1};
} else {
return UnionIdOut{input_.distance2, input_.levelid2};
}
}
struct DifferenceIdIn {
float distance1;
float levelid1;
float distance2;
float levelid2;
};
struct DifferenceIdOut {
float distance;
float levelid;
};
__device__ __forceinline__ DifferenceIdOut DifferenceIdImpl(DifferenceIdIn input_) {
if (-input_.distance1 > input_.distance2) {
return DifferenceIdOut{-input_.distance1, input_.levelid1};
} else {
return DifferenceIdOut{input_.distance2, input_.levelid2};
}
}
struct IntersectionIdIn {
float distance1;
float levelid1;
float distance2;
float levelid2;
};
struct IntersectionIdOut {
float distance;
float levelid;
};
__device__ __forceinline__ IntersectionIdOut IntersectionIdImpl(IntersectionIdIn input_) {
if (input_.distance1 > input_.distance2) {
return IntersectionIdOut{input_.distance1, input_.levelid1};
} else {
return IntersectionIdOut{input_.distance2, input_.levelid2};
}
}
struct ScaffoldIdIn {
float distance1;
float levelid1;
float distance2;
float levelid2;
float view_scaffold;
};
struct ScaffoldIdOut {
float distance;
float levelid;
};
#define SCAFFOLDEDOVERID_THICKNESS 0.0025
__device__ __forceinline__ float ScaffoldIdBorderSdf(float sdf) {
return abs(sdf + SCAFFOLDEDOVERID_THICKNESS) - SCAFFOLDEDOVERID_THICKNESS;
}
__device__ __forceinline__ float ScaffoldIdInnerSdf(float sdf) {
return sdf + SCAFFOLDEDOVERID_THICKNESS;
}
__device__ __forceinline__ ScaffoldIdOut ScaffoldIdImpl(ScaffoldIdIn input_) {
if(input_.view_scaffold == 0.0) {
return ScaffoldIdOut{input_.distance2, input_.levelid2};
}
float distance1 = max(input_.distance1, -ScaffoldIdBorderSdf(input_.distance2));
float distance2 = ScaffoldIdInnerSdf(input_.distance2);
if (distance1 < distance2) {
return ScaffoldIdOut{distance1, input_.levelid1};
} else {
return ScaffoldIdOut{distance2, input_.levelid2};
}
}
struct Level1Output {
float distance;
float levelid;
};
struct Level2Output {
float distance;
float levelid;
};
struct Level3Output {
float distance;
float levelid;
};
struct Level4Output {
float distance;
float levelid;
};
struct Level5Output {
float distance;
float levelid;
};
struct Level6Output {
float distance;
float levelid;
};
struct Level7Output {
float distance;
float levelid;
};
struct Level8Output {
float distance;
float levelid;
};
struct Level9Output {
float distance;
float levelid;
};
struct Level10Output {
float distance;
float levelid;
};
struct PositionInput {
float2 position;
float view_scaffold;
};