#pragma once
#include "Variation.h"
namespace EmberNs
{
///
/// Hemisphere.
///
template
class HemisphereVariation : public Variation
{
public:
HemisphereVariation(T weight = 1.0) : Variation("hemisphere", eVariationId::VAR_HEMISPHERE, weight, true) { }
VARCOPY(HemisphereVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T t = m_Weight / std::sqrt(helper.m_PrecalcSumSquares + 1);
helper.Out.x = helper.In.x * t;
helper.Out.y = helper.In.y * t;
helper.Out.z = t;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\treal_t t = " << weight << " / sqrt(precalcSumSquares + (real_t)(1.0));\n"
<< "\n"
<< "\t\tvOut.x = vIn.x * t;\n"
<< "\t\tvOut.y = vIn.y * t;\n"
<< "\t\tvOut.z = t;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Epispiral.
///
template
class EpispiralVariation : public ParametricVariation
{
public:
EpispiralVariation(T weight = 1.0) : ParametricVariation("epispiral", eVariationId::VAR_EPISPIRAL, weight, false, false, false, false, true)
{
Init();
}
PARVARCOPY(EpispiralVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T theta = helper.m_PrecalcAtanyx;
T t = (rand.Frand01() * m_Thickness) * (1 / std::cos(m_N * theta)) - m_Holes;
if (std::abs(t) != 0)
{
helper.Out.x = m_Weight * t * std::cos(theta);
helper.Out.y = m_Weight * t * std::sin(theta);
}
else
{
helper.Out.x = 0;
helper.Out.y = 0;
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string holes = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t theta = precalcAtanyx;\n"
<< "\t\treal_t t = (MwcNext01(mwc) * " << thickness << ") * (1 / cos(" << n << " * theta)) - " << holes << ";\n"
<< "\n"
<< "\t\tif (fabs(t) != 0)\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = " << weight << " * t * cos(theta);\n"
<< "\t\t\tvOut.y = " << weight << " * t * sin(theta);\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = 0;\n"
<< "\t\t\tvOut.y = 0;\n"
<< "\t\t}\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "epispiral_n", 6));
m_Params.push_back(ParamWithName(&m_Thickness, prefix + "epispiral_thickness"));
m_Params.push_back(ParamWithName(&m_Holes, prefix + "epispiral_holes", 1));
}
private:
T m_N;
T m_Thickness;
T m_Holes;
};
///
/// Bwraps.
/// Note, this is the same as bwraps7, which is the same as bwraps2 except for the precalc function.
///
template
class BwrapsVariation : public ParametricVariation
{
public:
BwrapsVariation(T weight = 1.0) : ParametricVariation("bwraps", eVariationId::VAR_BWRAPS, weight)
{
Init();
}
PARVARCOPY(BwrapsVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_BwrapsCellsize == 0)
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
T vx = helper.In.x;
T vy = helper.In.y;
T cx = (Floor(vx / m_BwrapsCellsize) + T(0.5)) * m_BwrapsCellsize;
T cy = (Floor(vy / m_BwrapsCellsize) + T(0.5)) * m_BwrapsCellsize;
T lx = vx - cx;
T ly = vy - cy;
if ((SQR(lx) + SQR(ly)) > m_R2)
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
lx *= m_G2;
ly *= m_G2;
T r = m_Rfactor / Zeps((SQR(lx) + SQR(ly)) / 4 + 1);
lx *= r;
ly *= r;
r = (SQR(lx) + SQR(ly)) / m_R2;
T theta = m_BwrapsInnerTwist * (1 - r) + m_BwrapsOuterTwist * r;
T s = std::sin(theta);
T c = std::cos(theta);
vx = cx + c * lx + s * ly;
vy = cy - s * lx + c * ly;
helper.Out.x = m_Weight * vx;
helper.Out.y = m_Weight * vy;
}
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string bwrapsCellsize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsSpace = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsGain = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsInnerTwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsOuterTwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string g2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string r2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rfactor = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif (" << bwrapsCellsize << " == 0)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * vIn.x;\n"
<< "\t\t vOut.y = " << weight << " * vIn.y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t vx = vIn.x;\n"
<< "\t\t real_t vy = vIn.y;\n"
<< "\t\t real_t cx = (floor(vx / " << bwrapsCellsize << ") + (real_t)(0.5)) * " << bwrapsCellsize << ";\n"
<< "\t\t real_t cy = (floor(vy / " << bwrapsCellsize << ") + (real_t)(0.5)) * " << bwrapsCellsize << ";\n"
<< "\t\t real_t lx = vx - cx;\n"
<< "\t\t real_t ly = vy - cy;\n"
<< "\n"
<< "\t\t if ((SQR(lx) + SQR(ly)) > " << r2 << ")\n"
<< "\t\t {\n"
<< "\t\t vOut.x = " << weight << " * vIn.x;\n"
<< "\t\t vOut.y = " << weight << " * vIn.y;\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t lx *= " << g2 << ";\n"
<< "\t\t ly *= " << g2 << ";\n"
<< "\n"
<< "\t\t real_t r = " << rfactor << " / Zeps(fma(lx, lx, SQR(ly)) / 4 + 1);\n"
<< "\n"
<< "\t\t lx *= r;\n"
<< "\t\t ly *= r;\n"
<< "\t\t r = fma(lx, lx, SQR(ly)) / " << r2 << ";\n"
<< "\n"
<< "\t\t real_t theta = fma(" << bwrapsInnerTwist << ", (1 - r), " << bwrapsOuterTwist << " * r);\n"
<< "\t\t real_t s = sin(theta);\n"
<< "\t\t real_t c = cos(theta);\n"
<< "\n"
<< "\t\t vx = fma(s, ly, fma(c, lx, cx));\n"
<< "\t\t vy = cy - s * lx + c * ly;\n"
<< "\n"
<< "\t\t vOut.x = " << weight << " * vx;\n"
<< "\t\t vOut.y = " << weight << " * vy;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
T radius = T(0.5) * (m_BwrapsCellsize / (1 + SQR(m_BwrapsSpace)));
m_G2 = SQR(m_BwrapsGain) + T(1.0e-6);
T maxBubble = m_G2 * radius;
if (maxBubble > 2)
maxBubble = 1;
else
maxBubble *= (1 / (SQR(maxBubble) / 4 + 1));
m_R2 = Zeps(SQR(radius));
m_Rfactor = radius / maxBubble;
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BwrapsCellsize, prefix + "bwraps_cellsize", 1));
m_Params.push_back(ParamWithName(&m_BwrapsSpace, prefix + "bwraps_space"));
m_Params.push_back(ParamWithName(&m_BwrapsGain, prefix + "bwraps_gain", 1));
m_Params.push_back(ParamWithName(&m_BwrapsInnerTwist, prefix + "bwraps_inner_twist"));
m_Params.push_back(ParamWithName(&m_BwrapsOuterTwist, prefix + "bwraps_outer_twist"));
m_Params.push_back(ParamWithName(true, &m_G2, prefix + "bwraps_g2"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_R2, prefix + "bwraps_r2"));
m_Params.push_back(ParamWithName(true, &m_Rfactor, prefix + "bwraps_rfactor"));
}
private:
T m_BwrapsCellsize;
T m_BwrapsSpace;
T m_BwrapsGain;
T m_BwrapsInnerTwist;
T m_BwrapsOuterTwist;
T m_G2;//Precalc.
T m_R2;
T m_Rfactor;
};
///
/// bwraps_rand.
/// By tatasz.
///
template
class BwrapsRandVariation : public ParametricVariation
{
public:
BwrapsRandVariation(T weight = 1.0) : ParametricVariation("bwraps_rand", eVariationId::VAR_BWRAPS_RAND, weight)
{
Init();
}
PARVARCOPY(BwrapsRandVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_CellSize == 0)
{
helper.Out.x = helper.In.x * m_Weight;
helper.Out.y = helper.In.y * m_Weight;
}
else
{
T Cx = (Floor(helper.In.x * m_InvCellSize) + T(0.5)) * m_CellSize;
T Cy = (Floor(helper.In.y * m_InvCellSize) + T(0.5)) * m_CellSize;
T Lx = helper.In.x - Cx;
T Ly = helper.In.y - Cy;
T radius;
if (m_Symm == 0)
radius = m_HalfCellSizeOver1pSpaceSq * VarFuncs::HashShadertoy(Cx, Cy, m_Seed);
else
radius = m_HalfCellSizeOver1pSpaceSq * VarFuncs::HashShadertoy(SQR(Cx), SQR(Cy), m_Seed);
T mb = m_G2 * radius;
T max_bubble;
if (mb > 2)
max_bubble = 1;
else
max_bubble = mb / (mb * mb * T(0.25) + 1);
T r2 = SQR(radius);
if (SQR(Lx) + SQR(Ly) > r2)
{
helper.Out.x = helper.In.x * m_Weight;
helper.Out.y = helper.In.y * m_Weight;
}
else
{
T rfactor = radius / Zeps(max_bubble);
T Lx2 = Lx * m_G2;
T Ly2 = Ly * m_G2;
T r = rfactor / ((SQR(Lx2) + SQR(Ly2)) * T(0.25) + 1);
T Lx3 = Lx2 * r;
T Ly3 = Ly2 * r;
T r_2 = (SQR(Lx3) + SQR(Ly3)) / Zeps(r2);
T theta = m_InnerTwist * (1 - r_2) + m_OuterTwist * r_2;
T ct = std::cos(theta);
T st = std::sin(theta);
helper.Out.x = (Cx + ct * Lx3 + st * Ly3) * m_Weight;
helper.Out.y = (Cy - st * Lx3 + ct * Ly3) * m_Weight;
}
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string cellsize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string space = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string gain = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string innertwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string outertwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string symm = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string seed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string invcellsize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string g2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string spacesq = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string halfcellsizeover1pspacesq = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif (" << cellsize << " == 0)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = vIn.x * " << weight << ";\n"
<< "\t\t vOut.y = vIn.y * " << weight << ";\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t Cx = (floor(vIn.x * " << invcellsize << ") + 0.5) * " << cellsize << ";\n"
<< "\t\t real_t Cy = (floor(vIn.y * " << invcellsize << ") + 0.5) * " << cellsize << ";\n"
<< "\t\t real_t Lx = vIn.x - Cx;\n"
<< "\t\t real_t Ly = vIn.y - Cy;\n"
<< "\t\t real_t radius;\n"
<< "\n"
<< "\t\t if (" << symm << " == 0)\n"
<< "\t\t radius = " << halfcellsizeover1pspacesq << " * HashShadertoy(Cx, Cy, " << seed << ");\n"
<< "\t\t else\n"
<< "\t\t radius = " << halfcellsizeover1pspacesq << " * HashShadertoy(SQR(Cx), SQR(Cy), " << seed << ");\n"
<< "\n"
<< "\t\t real_t mb = " << g2 << " * radius;\n"
<< "\t\t real_t max_bubble;\n"
<< "\n"
<< "\t\t if (mb > 2)\n"
<< "\t\t max_bubble = 1;\n"
<< "\t\t else\n"
<< "\t\t max_bubble = mb / fma(SQR(mb), (real_t)(0.25), (real_t)(1.0));\n"
<< "\n"
<< "\t\t real_t r2 = SQR(radius);\n"
<< "\n"
<< "\t\t if (SQR(Lx) + SQR(Ly) > r2)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = vIn.x * " << weight << ";\n"
<< "\t\t vOut.y = vIn.y * " << weight << ";\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t real_t rfactor = radius / Zeps(max_bubble);\n"
<< "\t\t real_t Lx2 = Lx * " << g2 << ";\n"
<< "\t\t real_t Ly2 = Ly * " << g2 << ";\n"
<< "\t\t real_t r = rfactor / fma(fma(Lx2, Lx2, SQR(Ly2)), (real_t)(0.25), (real_t)(1.0));\n"
<< "\t\t real_t Lx3 = Lx2 * r;\n"
<< "\t\t real_t Ly3 = Ly2 * r;\n"
<< "\t\t real_t r_2 = fma(Lx3, Lx3, SQR(Ly3)) / Zeps(r2);\n"
<< "\t\t real_t theta = " << innertwist << " * (1.0 - r_2) + " << outertwist << " * r_2;\n"
<< "\t\t real_t ct = cos(theta);\n"
<< "\t\t real_t st = sin(theta);\n"
<< "\n"
<< "\t\t vOut.x = (Cx + ct * Lx3 + st * Ly3) * " << weight << ";\n"
<< "\t\t vOut.y = (Cy - st * Lx3 + ct * Ly3) * " << weight << ";\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_G2 = SQR(m_Gain);
m_InvCellSize = 1 / Zeps(m_CellSize);
m_SpaceSq = SQR(m_Space);
m_HalfCellSizeOver1pSpaceSq = T(0.5) * (m_CellSize / (1 + m_SpaceSq));
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps", "Fract", "HashShadertoy" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_CellSize, prefix + "bwraps_rand_cellsize", 1));
m_Params.push_back(ParamWithName(&m_Space, prefix + "bwraps_rand_space"));
m_Params.push_back(ParamWithName(&m_Gain, prefix + "bwraps_rand_gain", 2));
m_Params.push_back(ParamWithName(&m_InnerTwist, prefix + "bwraps_rand_inner_twist"));
m_Params.push_back(ParamWithName(&m_OuterTwist, prefix + "bwraps_rand_outer_twist"));
m_Params.push_back(ParamWithName(&m_Symm, prefix + "bwraps_rand_symm"));
m_Params.push_back(ParamWithName(&m_Seed, prefix + "bwraps_rand_seed", 1));
m_Params.push_back(ParamWithName(true, &m_InvCellSize, prefix + "bwraps_rand_inv_cellsize"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_G2, prefix + "bwraps_rand_g2"));
m_Params.push_back(ParamWithName(true, &m_SpaceSq, prefix + "bwraps_rand_space_sq"));
m_Params.push_back(ParamWithName(true, &m_HalfCellSizeOver1pSpaceSq, prefix + "bwraps_rand_half_cellsize_over_1_plus_space_sq"));
}
private:
T m_CellSize;
T m_Space;
T m_Gain;
T m_InnerTwist;
T m_OuterTwist;
T m_Symm;
T m_Seed;
T m_InvCellSize;//Precalc.
T m_G2;
T m_SpaceSq;
T m_HalfCellSizeOver1pSpaceSq;
};
///
/// BlurCircle.
///
template
class BlurCircleVariation : public Variation
{
public:
BlurCircleVariation(T weight = 1.0) : Variation("blur_circle", eVariationId::VAR_BLUR_CIRCLE, weight) { }
VARCOPY(BlurCircleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = 2 * rand.Frand01() - 1;
T y = 2 * rand.Frand01() - 1;
T absx = x;
T absy = y;
T side, perimeter;
if (absx < 0)
absx = absx * -1;
if (absy < 0)
absy = absy * -1;
if (absx >= absy)
{
if (x >= absy)
perimeter = absx + y;
else
perimeter = 5 * absx - y;
side = absx;
}
else
{
if (y >= absx)
perimeter = 3 * absy - x;
else
perimeter = 7 * absy + x;
side = absy;
}
T r = m_Weight * side;
T val = T(M_PI_4) * perimeter / side - T(M_PI_4);
T sina = std::sin(val);
T cosa = std::cos(val);
helper.Out.x = r * cosa;
helper.Out.y = r * sina;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
ss << "\t{\n"
<< "\t\treal_t x = fma((real_t)(2.0), MwcNext01(mwc), (real_t)(-1.0));\n"
<< "\t\treal_t y = fma((real_t)(2.0), MwcNext01(mwc), (real_t)(-1.0));\n"
<< "\t\treal_t absx = x;\n"
<< "\t\treal_t absy = y;\n"
<< "\t\treal_t side, perimeter;\n"
<< "\t\t\n"
<< "\t\tif (absx < 0)\n"
<< "\t\t absx = absx * -1;\n"
<< "\n"
<< "\t\tif (absy < 0)\n"
<< "\t\t absy = absy * -1;\n"
<< "\n"
<< "\t\tif (absx >= absy)\n"
<< "\t\t{\n"
<< "\t\t if (x >= absy)\n"
<< "\t\t perimeter = absx + y;\n"
<< "\t\t else\n"
<< "\t\t perimeter = fma((real_t)(5.0), absx, -y);\n"
<< "\n"
<< "\t\t side = absx;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (y >= absx)\n"
<< "\t\t perimeter = fma((real_t)(3.0), absy, -x);\n"
<< "\t\t else\n"
<< "\t\t perimeter = fma((real_t)(7.0), absy, x);\n"
<< "\n"
<< "\t\t side = absy;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r = " << weight << " * side;\n"
<< "\t\treal_t val = MPI4 * perimeter / side - MPI4;\n"
<< "\t\treal_t sina = sin(val);\n"
<< "\t\treal_t cosa = cos(val);\n"
<< "\n"
<< "\t\tvOut.x = r * cosa;\n"
<< "\t\tvOut.y = r * sina;\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// BlurZoom.
///
template
class BlurZoomVariation : public ParametricVariation
{
public:
BlurZoomVariation(T weight = 1.0) : ParametricVariation("blur_zoom", eVariationId::VAR_BLUR_ZOOM, weight)
{
Init();
}
PARVARCOPY(BlurZoomVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T z = 1 + m_BlurZoomLength * rand.Frand01();
helper.Out.x = m_Weight * ((helper.In.x - m_BlurZoomX) * z + m_BlurZoomX);
helper.Out.y = m_Weight * ((helper.In.y - m_BlurZoomY) * z - m_BlurZoomY);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string blurZoomLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurZoomX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurZoomY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t z = fma(" << blurZoomLength << ", MwcNext01(mwc), 1);\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * fma((vIn.x - " << blurZoomX << "), z, " << blurZoomX << ");\n"
<< "\t\tvOut.y = " << weight << " * fma((vIn.y - " << blurZoomY << "), z, -" << blurZoomY << ");\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BlurZoomLength, prefix + "blur_zoom_length"));
m_Params.push_back(ParamWithName(&m_BlurZoomX, prefix + "blur_zoom_x"));
m_Params.push_back(ParamWithName(&m_BlurZoomY, prefix + "blur_zoom_y"));
}
private:
T m_BlurZoomLength;
T m_BlurZoomX;
T m_BlurZoomY;
};
///
/// BlurPixelize.
///
template
class BlurPixelizeVariation : public ParametricVariation
{
public:
BlurPixelizeVariation(T weight = 1.0) : ParametricVariation("blur_pixelize", eVariationId::VAR_BLUR_PIXELIZE, weight)
{
Init();
}
PARVARCOPY(BlurPixelizeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = T(Floor(helper.In.x * m_InvSize));
T y = T(Floor(helper.In.y * m_InvSize));
helper.Out.x = m_V * (x + m_BlurPixelizeScale * (rand.Frand01() - T(0.5)) + T(0.5));
helper.Out.y = m_V * (y + m_BlurPixelizeScale * (rand.Frand01() - T(0.5)) + T(0.5));
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string blurPixelizeSize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurPixelizeScale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string v = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string invSize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = floor(vIn.x * " << invSize << ");\n"
<< "\t\treal_t y = floor(vIn.y * " << invSize << ");\n"
<< "\n"
<< "\t\tvOut.x = " << v << " * fma(" << blurPixelizeScale << ", (MwcNext01(mwc) - (real_t)(0.5)), x + (real_t)(0.5));\n"
<< "\t\tvOut.y = " << v << " * fma(" << blurPixelizeScale << ", (MwcNext01(mwc) - (real_t)(0.5)), y + (real_t)(0.5));\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_V = m_Weight * m_BlurPixelizeSize;
m_InvSize = 1 / m_BlurPixelizeSize;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BlurPixelizeSize, prefix + "blur_pixelize_size", T(0.1), eParamType::REAL, EPS));
m_Params.push_back(ParamWithName(&m_BlurPixelizeScale, prefix + "blur_pixelize_scale", 1));
m_Params.push_back(ParamWithName(true, &m_V, prefix + "blur_pixelize_v"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_InvSize, prefix + "blur_pixelize_inv_size"));
}
private:
T m_BlurPixelizeSize;
T m_BlurPixelizeScale;
T m_V;//Precalc.
T m_InvSize;
};
///
/// Crop.
///
template
class CropVariation : public ParametricVariation
{
public:
CropVariation(T weight = 1.0) : ParametricVariation("crop", eVariationId::VAR_CROP, weight)
{
Init();
}
PARVARCOPY(CropVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = helper.In.x;
T y = helper.In.y;
if (((x < m_X0_) || (x > m_X1_) || (y < m_Y0_) || (y > m_Y1_)) && m_Z != 0)
{
x = 0;
y = 0;
}
else
{
if (x < m_X0_)
x = m_X0_ + rand.Frand01() * m_W;
else if (x > m_X1_)
x = m_X1_ - rand.Frand01() * m_W;
if (y < m_Y0_)
y = m_Y0_ + rand.Frand01() * m_H;
else if (y > m_Y1_)
y = m_Y1_ - rand.Frand01() * m_H;
}
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string x0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string z = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x0_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y0_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x1_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y1_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string w = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string h = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = vIn.x;\n"
<< "\t\treal_t y = vIn.y;\n"
<< "\n"
<< "\t\tif (((x < " << x0_ << ") || (x > " << x1_ << ") || (y < " << y0_ << ") || (y > " << y1_ << ")) && " << z << " != 0)\n"
<< "\t\t{\n"
<< "\t\t x = 0;\n"
<< "\t\t y = 0;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (x < " << x0_ << ")\n"
<< "\t\t x = fma(MwcNext01(mwc), " << w << ", " << x0_ << ");\n"
<< "\t\t else if (x > " << x1_ << ")\n"
<< "\t\t x = " << x1_ << " - MwcNext01(mwc) * " << w << ";\n"
<< "\t\t\n"
<< "\t\t if (y < " << y0_ << ")\n"
<< "\t\t y = fma(MwcNext01(mwc), " << h << ", " << y0_ << ");\n"
<< "\t\t else if (y > " << y1_ << ")\n"
<< "\t\t y = " << y1_ << " - MwcNext01(mwc) * " << h << ";\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * x;\n"
<< "\t\tvOut.y = " << weight << " * y;\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
if (m_X0 < m_X1)
{
m_X0_ = m_X0;
m_X1_ = m_X1;
}
else
{
m_X0_ = m_X1;
m_X1_ = m_X0;
}
if (m_Y0 < m_Y1)
{
m_Y0_ = m_Y0;
m_Y1_ = m_Y1;
}
else
{
m_Y0_ = m_Y1;
m_Y1_ = m_Y0;
}
m_W = (m_X1_ - m_X0_) * T(0.5) * m_S;
m_H = (m_Y1_ - m_Y0_) * T(0.5) * m_S;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X0, prefix + "crop_left", -1));
m_Params.push_back(ParamWithName(&m_Y0, prefix + "crop_top", -1));
m_Params.push_back(ParamWithName(&m_X1, prefix + "crop_right", 1));
m_Params.push_back(ParamWithName(&m_Y1, prefix + "crop_bottom", 1));
m_Params.push_back(ParamWithName(&m_S, prefix + "crop_scatter_area", 0, eParamType::REAL, -1, 1));
m_Params.push_back(ParamWithName(&m_Z, prefix + "crop_zero", 0, eParamType::INTEGER, 0, 1));
m_Params.push_back(ParamWithName(true, &m_X0_, prefix + "crop_x0_"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Y0_, prefix + "crop_y0_"));
m_Params.push_back(ParamWithName(true, &m_X1_, prefix + "crop_x1_"));
m_Params.push_back(ParamWithName(true, &m_Y1_, prefix + "crop_y1_"));
m_Params.push_back(ParamWithName(true, &m_W, prefix + "crop_w"));
m_Params.push_back(ParamWithName(true, &m_H, prefix + "crop_h"));
}
private:
T m_X0;
T m_Y0;
T m_X1;
T m_Y1;
T m_S;
T m_Z;
T m_X0_;//Precalc.
T m_Y0_;
T m_X1_;
T m_Y1_;
T m_W;
T m_H;
};
///
/// BCircle.
///
template
class BCircleVariation : public ParametricVariation
{
public:
BCircleVariation(T weight = 1.0) : ParametricVariation("bcircle", eVariationId::VAR_BCIRCLE, weight)
{
Init();
}
PARVARCOPY(BCircleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if ((helper.In.x == 0) && (helper.In.y == 0))
return;
T x = helper.In.x * m_Scale;
T y = helper.In.y * m_Scale;
T r = std::sqrt(SQR(x) + SQR(y));
if (r <= 1)
{
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
if (m_Bcbw != 0)
{
T ang = std::atan2(y, x);
T omega = (T(0.2) * m_Bcbw * rand.Frand01()) + 1;
T px = omega * std::cos(ang);
T py = omega * std::sin(ang);
helper.Out.x = m_Weight * px;
helper.Out.y = m_Weight * py;
}
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string borderWidth = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bcbw = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif ((vIn.x == 0) && (vIn.y == 0))\n"
<< "\t\t return;\n"
<< "\n"
<< "\t\treal_t x = vIn.x * " << scale << ";\n"
<< "\t\treal_t y = vIn.y * " << scale << ";\n"
<< "\t\treal_t r = sqrt(fma(x, x, SQR(y)));\n"
<< "\n"
<< "\t\tif (r <= 1)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * x;\n"
<< "\t\t vOut.y = " << weight << " * y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (" << bcbw << " != 0)\n"
<< "\t\t {\n"
<< "\t\t real_t ang = atan2(y, x);\n"
<< "\t\t real_t omega = fma((real_t)(0.2) * " << bcbw << ", MwcNext01(mwc), (real_t)(1.0));\n"
<< "\t\t real_t px = omega * cos(ang);\n"
<< "\t\t real_t py = omega * sin(ang);\n"
<< "\n"
<< "\t\t vOut.x = " << weight << " * px;\n"
<< "\t\t vOut.y = " << weight << " * py;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Bcbw = std::abs(m_BorderWidth);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Scale, prefix + "bcircle_scale", 1));
m_Params.push_back(ParamWithName(&m_BorderWidth, prefix + "bcircle_borderwidth"));
m_Params.push_back(ParamWithName(true, &m_Bcbw, prefix + "bcircle_bcbw"));//Precalc.
}
private:
T m_Scale;
T m_BorderWidth;
T m_Bcbw;//Precalc.
};
///
/// BlurLinear.
///
template
class BlurLinearVariation : public ParametricVariation
{
public:
BlurLinearVariation(T weight = 1.0) : ParametricVariation("blur_linear", eVariationId::VAR_BLUR_LINEAR, weight)
{
Init();
}
PARVARCOPY(BlurLinearVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_BlurLinearLength * rand.Frand01();
helper.Out.x = m_Weight * (helper.In.x + r * m_C);
helper.Out.y = m_Weight * (helper.In.y + r * m_S);
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string blurLinearLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurLinearAngle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = " << blurLinearLength << " * MwcNext01(mwc);\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * fma(r, " << c << ", vIn.x);\n"
<< "\t\tvOut.y = " << weight << " * fma(r, " << s << ", vIn.y);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
sincos(m_BlurLinearAngle, &m_S, &m_C);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BlurLinearLength, prefix + "blur_linear_length"));
m_Params.push_back(ParamWithName(&m_BlurLinearAngle, prefix + "blur_linear_angle", 0, eParamType::REAL_CYCLIC, 0, T(M_2PI)));
m_Params.push_back(ParamWithName(true, &m_S, prefix + "blur_linear_s"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_C, prefix + "blur_linear_c"));
}
private:
T m_BlurLinearLength;
T m_BlurLinearAngle;
T m_S;//Precalc.
T m_C;
};
///
/// BlurSquare.
///
template
class BlurSquareVariation : public ParametricVariation
{
public:
BlurSquareVariation(T weight = 1.0) : ParametricVariation("blur_square", eVariationId::VAR_BLUR_SQUARE, weight)
{
Init();
}
PARVARCOPY(BlurSquareVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_V * (rand.Frand01() - T(0.5));
helper.Out.y = m_V * (rand.Frand01() - T(0.5));
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string v = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params.
ss << "\t{\n"
<< "\t\tvOut.x = " << v << " * (MwcNext01(mwc) - (real_t)(0.5));\n"
<< "\t\tvOut.y = " << v << " * (MwcNext01(mwc) - (real_t)(0.5));\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_V = m_Weight * 2;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(true, &m_V, prefix + "blur_square_v"));//Precalcs only, no params.
}
private:
T m_V;
};
///
/// Flatten.
/// This uses in/out in a rare and different way.
///
template
class FlattenVariation : public Variation
{
public:
FlattenVariation(T weight = 1.0) : Variation("flatten", eVariationId::VAR_FLATTEN, weight) { }
VARCOPY(FlattenVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == eVariationType::VARTYPE_REG)//Rare and different usage of in/out.
{
helper.Out.x = helper.Out.y = helper.Out.z = 0;
outPoint.m_Z = 0;
}
else
{
helper.Out.x = helper.In.x;
helper.Out.y = helper.In.y;
helper.Out.z = 0;
}
}
virtual string OpenCLString() const override
{
ostringstream ss;
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss << "\t{\n"
<< "\t\tvOut.x = 0;\n"
<< "\t\tvOut.y = 0;\n"
<< "\t\tvOut.z = 0;\n"
<< "\t\toutPoint->m_Z = 0;\n"
<< "\t}\n";
}
else
{
ss << "\t{\n"
<< "\t\tvOut.x = vIn.x;\n"
<< "\t\tvOut.y = vIn.y;\n"
<< "\t\tvOut.z = 0;\n"
<< "\t}\n";
}
return ss.str();
}
};
///
/// Zblur.
/// This uses in/out in a rare and different way.
///
template
class ZblurVariation : public Variation
{
public:
ZblurVariation(T weight = 1.0) : Variation("zblur", eVariationId::VAR_ZBLUR, weight) { }
VARCOPY(ZblurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2);
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = " << weight << " * (MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) - (real_t)(2.0));\n"
<< "\t}\n";
return ss.str();
}
};
///
/// ZScale.
/// This uses in/out in a rare and different way.
///
template
class ZScaleVariation : public Variation
{
public:
ZScaleVariation(T weight = 1.0) : Variation("zscale", eVariationId::VAR_ZSCALE, weight) { }
VARCOPY(ZScaleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// ZTranslate.
/// This uses in/out in a rare and different way.
///
template
class ZTranslateVariation : public Variation
{
public:
ZTranslateVariation(T weight = 1.0) : Variation("ztranslate", eVariationId::VAR_ZTRANSLATE, weight) { }
VARCOPY(ZTranslateVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = " << weight << ";\n"
<< "\t}\n";
return ss.str();
}
};
///
/// zcone.
/// This uses in/out in a rare and different way.
///
template
class ZConeVariation : public Variation
{
public:
ZConeVariation(T weight = 1.0) : Variation("zcone", eVariationId::VAR_ZCONE, weight, true, true) { }
VARCOPY(ZConeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == eVariationType::VARTYPE_REG)//Rare and different usage of in/out.
{
helper.Out.x = helper.Out.y = 0;
}
else
{
helper.Out.x = helper.In.x;
helper.Out.y = helper.In.y;
}
helper.Out.z = m_Weight * helper.m_PrecalcSqrtSumSquares;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss << "\t\tvOut.x = vOut.y = 0;\n";
}
else
{
ss << "\t\tvOut.x = vIn.x;\n"
<< "\t\tvOut.y = vIn.y;\n";
}
ss << "\t\tvOut.z = " << weight << " * precalcSqrtSumSquares;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Blur3D.
///
template
class Blur3DVariation : public Variation
{
public:
Blur3DVariation(T weight = 1.0) : Variation("blur3D", eVariationId::VAR_BLUR3D, weight) { }
VARCOPY(Blur3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T angle = rand.Frand01() * M_2PI;
T r = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2);
T angle2 = rand.Frand01() * T(M_PI);
T sina = std::sin(angle);
T cosa = std::cos(angle);
T sinb = std::sin(angle2);
T cosb = std::cos(angle2);
helper.Out.x = r * sinb * cosa;
helper.Out.y = r * sinb * sina;
helper.Out.z = r * cosb;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\treal_t angle = MwcNext01(mwc) * M_2PI;\n"
<< "\t\treal_t r = " << weight << " * (MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) - (real_t)(2.0));\n"
<< "\t\treal_t angle2 = MwcNext01(mwc) * MPI;\n"
<< "\t\treal_t sina = sin(angle);\n"
<< "\t\treal_t cosa = cos(angle);\n"
<< "\t\treal_t sinb = sin(angle2);\n"
<< "\t\treal_t cosb = cos(angle2);\n"
<< "\n"
<< "\t\tvOut.x = r * sinb * cosa;\n"
<< "\t\tvOut.y = r * sinb * sina;\n"
<< "\t\tvOut.z = r * cosb;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Spherical3D.
///
template
class Spherical3DVariation : public Variation
{
public:
Spherical3DVariation(T weight = 1.0) : Variation("Spherical3D", eVariationId::VAR_SPHERICAL3D, weight, true) { }
VARCOPY(Spherical3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r2 = m_Weight / Zeps(helper.m_PrecalcSumSquares + SQR(helper.In.z));
helper.Out.x = r2 * helper.In.x;
helper.Out.y = r2 * helper.In.y;
helper.Out.z = r2 * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\treal_t r2 = " << weight << " / Zeps(fma(vIn.z, vIn.z, precalcSumSquares));\n"
<< "\n"
<< "\t\tvOut.x = r2 * vIn.x;\n"
<< "\t\tvOut.y = r2 * vIn.y;\n"
<< "\t\tvOut.z = r2 * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
};
///
/// Curl3D.
///
template
class Curl3DVariation : public ParametricVariation
{
public:
Curl3DVariation(T weight = 1.0) : ParametricVariation("curl3D", eVariationId::VAR_CURL3D, weight, true)
{
Init();
}
PARVARCOPY(Curl3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r2 = helper.m_PrecalcSumSquares + SQR(helper.In.z);
T r = m_Weight / Zeps(r2 * m_C2 + m_C2x * helper.In.x - m_C2y * helper.In.y + m_C2z * helper.In.z + 1);
helper.Out.x = r * (helper.In.x + m_Cx * r2);
helper.Out.y = r * (helper.In.y - m_Cy * r2);
helper.Out.z = r * (helper.In.z + m_Cz * r2);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string cx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cz = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2z = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r2 = fma(vIn.z, vIn.z, precalcSumSquares);\n"
<< "\t\treal_t r = " << weight << " / Zeps(r2 * " << c2 << " + " << c2x << " * vIn.x - " << c2y << " * vIn.y + " << c2z << " * vIn.z + (real_t)(1.0));\n"
<< "\n"
<< "\t\tvOut.x = r * fma(" << cx << ", r2, vIn.x);\n"
<< "\t\tvOut.y = r * (vIn.y - " << cy << " * r2);\n"
<< "\t\tvOut.z = r * fma(" << cz << ", r2, vIn.z);\n"
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
virtual void Precalc() override
{
m_C2x = 2 * m_Cx;
m_C2y = 2 * m_Cy;
m_C2z = 2 * m_Cz;
m_C2 = SQR(m_Cx) + SQR(m_Cy) + SQR(m_Cz);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Cx, prefix + "curl3D_cx"));
m_Params.push_back(ParamWithName(&m_Cy, prefix + "curl3D_cy"));
m_Params.push_back(ParamWithName(&m_Cz, prefix + "curl3D_cz"));
m_Params.push_back(ParamWithName(true, &m_C2, prefix + "curl3D_c2"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "curl3D_c2x"));
m_Params.push_back(ParamWithName(true, &m_C2y, prefix + "curl3D_c2y"));
m_Params.push_back(ParamWithName(true, &m_C2z, prefix + "curl3D_c2z"));
}
private:
T m_Cx;
T m_Cy;
T m_Cz;
T m_C2;//Precalc.
T m_C2x;
T m_C2y;
T m_C2z;
};
///
/// Disc3D.
///
template
class Disc3DVariation : public ParametricVariation
{
public:
Disc3DVariation(T weight = 1.0) : ParametricVariation("disc3d", eVariationId::VAR_DISC3D, weight, true, true, false, true, false)
{
Init();
}
PARVARCOPY(Disc3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = helper.m_PrecalcSqrtSumSquares;
T temp = r * m_Pi;
T sr = std::sin(temp);
T cr = std::cos(temp);
T vv = m_Weight * helper.m_PrecalcAtanxy / Zeps(m_Pi);
helper.Out.x = vv * sr;
helper.Out.y = vv * cr;
helper.Out.z = vv * (r * std::cos(helper.In.z));
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = precalcSqrtSumSquares;\n"
<< "\t\treal_t temp = r * " << pi << ";\n"
<< "\t\treal_t sr = sin(temp);\n"
<< "\t\treal_t cr = cos(temp);\n"
<< "\t\treal_t vv = " << weight << " * precalcAtanxy / Zeps(" << pi << ");\n"
<< "\n"
<< "\t\tvOut.x = vv * sr;\n"
<< "\t\tvOut.y = vv * cr;\n"
<< "\t\tvOut.z = vv * (r * cos(vIn.z));\n"
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Pi, prefix + "disc3d_pi", T(M_PI)));
}
private:
T m_Pi;
};
///
/// Boarders2.
///
template
class Boarders2Variation : public ParametricVariation
{
public:
Boarders2Variation(T weight = 1.0) : ParametricVariation("boarders2", eVariationId::VAR_BOARDERS2, weight)
{
Init();
}
PARVARCOPY(Boarders2Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T roundX = T(int(helper.In.x >= 0 ? int(helper.In.x + T(0.5)) : int(helper.In.x - T(0.5))));
T roundY = T(int(helper.In.y >= 0 ? int(helper.In.y + T(0.5)) : int(helper.In.y - T(0.5))));
T offsetX = helper.In.x - roundX;
T offsetY = helper.In.y - roundY;
if (rand.Frand01() >= m_Cr)
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY);
}
else
{
if (std::abs(offsetX) >= std::abs(offsetY))
{
if (offsetX >= 0)
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX + m_Cl);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY + m_Cl * offsetY / offsetX);
}
else
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX - m_Cl);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY - m_Cl * offsetY / offsetX);
}
}
else
{
if (offsetY >= 0)
{
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY + m_Cl);
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX + offsetX / offsetY * m_Cl);
}
else
{
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY - m_Cl);
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX - offsetX / offsetY * m_Cl);
}
}
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string l = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string absc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cl = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cr = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t roundX = (real_t)(int)(vIn.x >= 0 ? (int)(vIn.x + (real_t)(0.5)) : (int)(vIn.x - (real_t)(0.5)));\n"
<< "\t\treal_t roundY = (real_t)(int)(vIn.y >= 0 ? (int)(vIn.y + (real_t)(0.5)) : (int)(vIn.y - (real_t)(0.5)));\n"
<< "\t\treal_t offsetX = vIn.x - roundX;\n"
<< "\t\treal_t offsetY = vIn.y - roundY;\n"
<< "\n"
<< "\t\tif (MwcNext01(mwc) >= " << cr << ")\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * fma(offsetX, " << absc << ", roundX);\n"
<< "\t\t vOut.y = " << weight << " * fma(offsetY, " << absc << ", roundY);\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (fabs(offsetX) >= fabs(offsetY))\n"
<< "\t\t {\n"
<< "\t\t if (offsetX >= 0)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = " << weight << " * fma(offsetX, " << absc << ", roundX + " << cl << ");\n"
<< "\t\t vOut.y = " << weight << " * (fma(offsetY, " << absc << ", roundY) + " << cl << " * offsetY / offsetX);\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = " << weight << " * fma(offsetX, " << absc << ", roundX - " << cl << ");\n"
<< "\t\t vOut.y = " << weight << " * (fma(offsetY, " << absc << ", roundY) - " << cl << " * offsetY / offsetX);\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t if(offsetY >= 0)\n"
<< "\t\t {\n"
<< "\t\t vOut.y = " << weight << " * fma(offsetY, " << absc << ", roundY + " << cl << ");\n"
<< "\t\t vOut.x = " << weight << " * (fma(offsetX, " << absc << ", roundX) + offsetX / offsetY * " << cl << ");\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.y = " << weight << " * fma(offsetY, " << absc << ", roundY - " << cl << ");\n"
<< "\t\t vOut.x = " << weight << " * (fma(offsetX, " << absc << ", roundX) - offsetX / offsetY * " << cl << ");\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
T c = Zeps(std::abs(m_C));
T cl = Zeps(std::abs(m_Left));
T cr = Zeps(std::abs(m_Right));
m_AbsC = c;
m_Cl = c * cl;
m_Cr = c + (c * cr);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_C, prefix + "boarders2_c", T(0.5)));
m_Params.push_back(ParamWithName(&m_Left, prefix + "boarders2_left", T(0.5)));
m_Params.push_back(ParamWithName(&m_Right, prefix + "boarders2_right", T(0.5)));
m_Params.push_back(ParamWithName(true, &m_AbsC, prefix + "boarders2_cabs"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cl, prefix + "boarders2_cl"));
m_Params.push_back(ParamWithName(true, &m_Cr, prefix + "boarders2_cr"));
}
private:
T m_C;
T m_Left;
T m_Right;
T m_AbsC;//Precalc.
T m_Cl;
T m_Cr;
};
///
/// Cardioid.
///
template
class CardioidVariation : public ParametricVariation
{
public:
CardioidVariation(T weight = 1.0) : ParametricVariation("cardioid", eVariationId::VAR_CARDIOID, weight, true, true, true, false, true)
{
Init();
}
PARVARCOPY(CardioidVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_Weight * std::sqrt(helper.m_PrecalcSumSquares + std::sin(helper.m_PrecalcAtanyx * m_A) + 1);
helper.Out.x = r * helper.m_PrecalcCosa;
helper.Out.y = r * helper.m_PrecalcSina;
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = " << weight << " * sqrt(precalcSumSquares + sin(precalcAtanyx * " << a << ") + 1);\n"
<< "\n"
<< "\t\tvOut.x = r * precalcCosa;\n"
<< "\t\tvOut.y = r * precalcSina;\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_A, prefix + "cardioid_a", 1));
}
private:
T m_A;
};
///
/// Checks.
///
template
class ChecksVariation : public ParametricVariation
{
public:
ChecksVariation(T weight = 1.0) : ParametricVariation("checks", eVariationId::VAR_CHECKS, weight)
{
Init();
}
PARVARCOPY(ChecksVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T dx, dy;
T rnx = m_Rnd * rand.Frand01();
T rny = m_Rnd * rand.Frand01();
int isXY = int(VarFuncs::LRint(helper.In.x * m_Cs) + VarFuncs::LRint(helper.In.y * m_Cs));
if (isXY & 1)
{
dx = m_Ncx + rnx;
dy = m_Ncy;
}
else
{
dx = m_Cx;
dy = m_Cy + rny;
}
helper.Out.x = m_Weight * (helper.In.x + dx);
helper.Out.y = m_Weight * (helper.In.y + dy);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string size = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rnd = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cs = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ncx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ncy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t dx, dy;\n"
<< "\t\treal_t rnx = " << rnd << " * MwcNext01(mwc);\n"
<< "\t\treal_t rny = " << rnd << " * MwcNext01(mwc);\n"
<< "\n"
<< "\t\tint isXY = (int)(LRint(vIn.x * " << cs << ") + LRint(vIn.y * " << cs << "));\n"
<< "\n"
<< "\t\tif (isXY & 1)\n"
<< "\t\t{\n"
<< "\t\t dx = " << ncx << " + rnx;\n"
<< "\t\t dy = " << ncy << ";\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t dx = " << cx << ";\n"
<< "\t\t dy = " << cy << " + rny;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * (vIn.x + dx);\n"
<< "\t\tvOut.y = " << weight << " * (vIn.y + dy);\n"
<< "\t\tvOut.z = " << weight << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "LRint" };
}
virtual void Precalc() override
{
m_Cs = 1 / Zeps(m_Size);
m_Cx = m_X;
m_Cy = m_Y;
m_Ncx = -m_X;
m_Ncy = -m_Y;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X, prefix + "checks_x", T(0.5)));
m_Params.push_back(ParamWithName(&m_Y, prefix + "checks_y", T(0.5)));
m_Params.push_back(ParamWithName(&m_Size, prefix + "checks_size", T(0.5)));
m_Params.push_back(ParamWithName