#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(&m_Rnd, prefix + "checks_rnd")); m_Params.push_back(ParamWithName(true, &m_Cs, prefix + "checks_cs"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "checks_cx")); m_Params.push_back(ParamWithName(true, &m_Cy, prefix + "checks_cy")); m_Params.push_back(ParamWithName(true, &m_Ncx, prefix + "checks_ncx")); m_Params.push_back(ParamWithName(true, &m_Ncy, prefix + "checks_ncy")); } private: T m_X; T m_Y; T m_Size; T m_Rnd; T m_Cs;//Precalc. T m_Cx; T m_Cy; T m_Ncx; T m_Ncy; }; /// /// Circlize. /// template class CirclizeVariation : public ParametricVariation { public: CirclizeVariation(T weight = 1.0) : ParametricVariation("circlize", eVariationId::VAR_CIRCLIZE, weight) { Init(); } PARVARCOPY(CirclizeVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T side; T perimeter; T r, val; T absx = std::abs(helper.In.x); T absy = std::abs(helper.In.y); if (absx >= absy) { if (helper.In.x >= absy) perimeter = absx + helper.In.y; else perimeter = 5 * absx - helper.In.y; side = absx; } else { if (helper.In.y >= absx) perimeter = 3 * absy - helper.In.x; else perimeter = 7 * absy + helper.In.x; side = absy; } r = m_Vvar4Pi * side + m_Hole; val = T(M_PI_4) * perimeter / side - T(M_PI_4); helper.Out.x = r * std::cos(val); helper.Out.y = r * std::sin(val); 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 hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vvar4pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t side;\n" << "\t\treal_t perimeter;\n" << "\t\treal_t absx = fabs(vIn.x);\n" << "\t\treal_t absy = fabs(vIn.y);\n" << "\n" << "\t\tif (absx >= absy)\n" << "\t\t{\n" << "\t\t if (vIn.x >= absy)\n" << "\t\t perimeter = absx + vIn.y;\n" << "\t\t else\n" << "\t\t perimeter = fma((real_t)(5.0), absx, -vIn.y);\n" << "\n" << "\t\t side = absx;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (vIn.y >= absx)\n" << "\t\t perimeter = fma((real_t)(3.0), absy, -vIn.x);\n" << "\t\t else\n" << "\t\t perimeter = fma((real_t)(7.0), absy, vIn.x);\n" << "\n" << "\t\t side = absy;\n" << "\t\t}\n" << "\n" << "\t\treal_t r = fma(" << vvar4pi << ", side, " << hole << ");\n" << "\t\treal_t val = MPI4 * perimeter / side - MPI4;\n" << "\n" << "\t\tvOut.x = r * cos(val);\n" << "\t\tvOut.y = r * sin(val);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Vvar4Pi = m_Weight / T(M_PI_4); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Hole, prefix + "circlize_hole")); m_Params.push_back(ParamWithName(true, &m_Vvar4Pi, prefix + "circlize_vvar4pi"));//Precalc. } private: T m_Hole; T m_Vvar4Pi;//Precalc. }; /// /// Circlize2. /// template class Circlize2Variation : public ParametricVariation { public: Circlize2Variation(T weight = 1.0) : ParametricVariation("circlize2", eVariationId::VAR_CIRCLIZE2, weight) { Init(); } PARVARCOPY(Circlize2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T side; T perimeter; T absx = std::abs(helper.In.x); T absy = std::abs(helper.In.y); if (absx >= absy) { if (helper.In.x >= absy) perimeter = absx + helper.In.y; else perimeter = 5 * absx - helper.In.y; side = absx; } else { if (helper.In.y >= absx) perimeter = 3 * absy - helper.In.x; else perimeter = 7 * absy + helper.In.x; side = absy; } T r = m_Weight * (side + m_Hole); T val = T(M_PI_4) * perimeter / side - T(M_PI_4); helper.Out.x = r * std::cos(val); helper.Out.y = r * std::sin(val); 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 hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t side;\n" << "\t\treal_t perimeter;\n" << "\t\treal_t absx = fabs(vIn.x);\n" << "\t\treal_t absy = fabs(vIn.y);\n" << "\n" << "\t\tif (absx >= absy)\n" << "\t\t{\n" << "\t\t if (vIn.x >= absy)\n" << "\t\t perimeter = absx + vIn.y;\n" << "\t\t else\n" << "\t\t perimeter = fma((real_t)(5.0), absx, -vIn.y);\n" << "\n" << "\t\t side = absx;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (vIn.y >= absx)\n" << "\t\t perimeter = fma((real_t)(3.0), absy, -vIn.x);\n" << "\t\t else\n" << "\t\t perimeter = fma((real_t)(7.0), absy, vIn.x);\n" << "\n" << "\t\t side = absy;\n" << "\t\t}\n" << "\n" << "\t\treal_t r = " << weight << " * (side + " << hole << ");\n" << "\t\treal_t val = MPI4 * perimeter / side - MPI4;\n" << "\n" << "\t\tvOut.x = r * cos(val);\n" << "\t\tvOut.y = r * sin(val);\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_Hole, prefix + "circlize2_hole")); } private: T m_Hole; }; /// /// CosWrap. /// template class CosWrapVariation : public ParametricVariation { public: CosWrapVariation(T weight = 1.0) : ParametricVariation("coswrap", eVariationId::VAR_COS_WRAP, weight) { Init(); } PARVARCOPY(CosWrapVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T x = T(0.5) * helper.In.x + T(0.5); T y = T(0.5) * helper.In.y + T(0.5); T bx = VarFuncs::Fabsmod(m_Fr * x); T by = VarFuncs::Fabsmod(m_Fr * y); T oscnapx = VarFuncs::Foscn(m_AmountX, m_Px); T oscnapy = VarFuncs::Foscn(m_AmountY, m_Py); helper.Out.x = -1 + m_Vv2 * Lerp(Lerp(x, VarFuncs::Fosc(x, T(4), m_Px), oscnapx), VarFuncs::Fosc(bx, T(4), m_Px), oscnapx);//Original did a direct assignment to outPoint, which is incompatible with Ember's design. helper.Out.y = -1 + m_Vv2 * Lerp(Lerp(y, VarFuncs::Fosc(y, T(4), m_Py), oscnapy), VarFuncs::Fosc(by, T(4), m_Py), oscnapy); helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss, ss2; int i = 0; ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string repeat = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string amountX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string amountY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string phaseX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string phaseY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ax = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ay = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string px = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string py = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string fr = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vv2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = fma((real_t)(0.5), vIn.x, (real_t)(0.5));\n" << "\t\treal_t y = fma((real_t)(0.5), vIn.y, (real_t)(0.5));\n" << "\t\treal_t bx = Fabsmod(" << fr << " * x);\n" << "\t\treal_t by = Fabsmod(" << fr << " * y);\n" << "\t\treal_t oscnapx = Foscn(" << amountX << ", " << px << ");\n" << "\t\treal_t oscnapy = Foscn(" << amountY << ", " << py << ");\n" << "\n" << "\t\tvOut.x = -1 + " << vv2 << " * Lerp(Lerp(x, Fosc(x, 4, " << px << "), oscnapx), Fosc(bx, 4, " << px << "), oscnapx);\n" << "\t\tvOut.y = -1 + " << vv2 << " * Lerp(Lerp(y, Fosc(y, 4, " << py << "), oscnapy), Fosc(by, 4, " << py << "), oscnapy);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Fabsmod", "Fosc", "Foscn", "Lerp" }; } virtual void Precalc() override { m_Ax = M_2PI * std::abs(m_AmountX); m_Ay = M_2PI * std::abs(m_AmountY); m_Px = T(M_PI) * m_PhaseX; m_Py = T(M_PI) * m_PhaseY; m_Fr = std::abs(m_Repeat); m_Vv2 = 2 * m_Weight; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Repeat, prefix + "coswrap_repeat", 1, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(&m_AmountX, prefix + "coswrap_amount_x")); m_Params.push_back(ParamWithName(&m_AmountY, prefix + "coswrap_amount_y")); m_Params.push_back(ParamWithName(&m_PhaseX, prefix + "coswrap_phase_x", 0, eParamType::REAL_CYCLIC, -1, 1)); m_Params.push_back(ParamWithName(&m_PhaseY, prefix + "coswrap_phase_y", 0, eParamType::REAL_CYCLIC, -1, 1)); m_Params.push_back(ParamWithName(true, &m_Ax, prefix + "coswrap_ax"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Ay, prefix + "coswrap_ay")); m_Params.push_back(ParamWithName(true, &m_Px, prefix + "coswrap_px")); m_Params.push_back(ParamWithName(true, &m_Py, prefix + "coswrap_py")); m_Params.push_back(ParamWithName(true, &m_Fr, prefix + "coswrap_fr")); m_Params.push_back(ParamWithName(true, &m_Vv2, prefix + "coswrap_vv2")); } private: T m_Repeat; T m_AmountX; T m_AmountY; T m_PhaseX; T m_PhaseY; T m_Ax;//Precalc. T m_Ay; T m_Px; T m_Py; T m_Fr; T m_Vv2; }; /// /// DeltaA. /// The original in deltaA.c in Apophysis used a precalc variable named v, but /// was unused in the calculation. So this remains a non-parametric variation with /// that precalc variable omitted. /// template class DeltaAVariation : public Variation { public: DeltaAVariation(T weight = 1.0) : Variation("deltaa", eVariationId::VAR_DELTA_A, weight) { } VARCOPY(DeltaAVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T s, c; T avgr = m_Weight * (std::sqrt(SQR(helper.In.y) + SQR(helper.In.x + 1)) / std::sqrt(SQR(helper.In.y) + SQR(helper.In.x - 1))); T avga = (std::atan2(helper.In.y, helper.In.x - 1) - std::atan2(helper.In.y, helper.In.x + 1)) / 2; sincos(avga, &s, &c); helper.Out.x = avgr * c; helper.Out.y = avgr * s; helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t xp1 = vIn.x + (real_t)(1.0);\n" << "\t\treal_t xm1 = vIn.x - (real_t)(1.0);\n" << "\t\treal_t avgr = " << weight << " * (sqrt(fma(vIn.y, vIn.y, SQR(xp1))) / sqrt(fma(vIn.y, vIn.y, SQR(xm1))));\n" << "\t\treal_t avga = (atan2(vIn.y, xm1) - atan2(vIn.y, xp1)) / 2;\n" << "\t\treal_t s = sin(avga);\n" << "\t\treal_t c = cos(avga);\n" << "\n" << "\t\tvOut.x = avgr * c;\n" << "\t\tvOut.y = avgr * s;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } }; /// /// Expo. /// template class ExpoVariation : public ParametricVariation { public: ExpoVariation(T weight = 1.0) : ParametricVariation("expo", eVariationId::VAR_EXPO, weight) { Init(); } PARVARCOPY(ExpoVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T expor = std::exp(helper.In.x * m_K - helper.In.y * m_T); T temp = helper.In.x * m_T + helper.In.y * m_K; T snv = std::sin(temp); T csv = std::cos(temp); helper.Out.x = m_Weight * expor * csv; helper.Out.y = m_Weight * expor * snv; 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 real = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string imag = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string k = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string t = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t expor = exp(fma(vIn.x, " << k << ", -(vIn.y * " << t << ")));\n" << "\t\treal_t temp = fma(vIn.x, " << t << ", (vIn.y * " << k << "));\n" << "\t\treal_t snv = sin(temp);\n" << "\t\treal_t csv = cos(temp);\n" << "\n" << "\t\tvOut.x = " << weight << " * expor * csv;\n" << "\t\tvOut.y = " << weight << " * expor * snv;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_K = T(0.5) * std::log(Zeps(SQR(m_Real) + SQR(m_Imag)));//Original used 1e-300, which isn't representable with a float. m_T = std::atan2(m_Imag, m_Real); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Real, prefix + "expo_real", -1)); m_Params.push_back(ParamWithName(&m_Imag, prefix + "expo_imaginary", 1)); m_Params.push_back(ParamWithName(true, &m_K, prefix + "expo_k"));//Precalc. m_Params.push_back(ParamWithName(true, &m_T, prefix + "expo_t")); } private: T m_Real; T m_Imag; T m_K;//Precalc. T m_T; }; /// /// Extrude. /// template class ExtrudeVariation : public ParametricVariation { public: ExtrudeVariation(T weight = 1.0) : ParametricVariation("extrude", eVariationId::VAR_EXTRUDE, weight) { Init(); } PARVARCOPY(ExtrudeVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { if (m_VarType == eVariationType::VARTYPE_REG) { helper.Out.x = helper.Out.y = helper.Out.z = 0; if (rand.Frand01() < m_RootFace) outPoint.m_Z = ClampGte0(m_Weight); else outPoint.m_Z = m_Weight * rand.Frand01(); } else { helper.Out.x = helper.In.x; helper.Out.y = helper.In.y; if (rand.Frand01() < m_RootFace) helper.Out.z = ClampGte0(m_Weight); else helper.Out.z = m_Weight * rand.Frand01(); } } virtual string OpenCLString() const override { ostringstream ss, ss2; intmax_t i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string rootFace = "parVars[" + ToUpper(m_Params[i++].Name()) + index; if (m_VarType == eVariationType::VARTYPE_REG) { ss << "\t{\n" << "\t\tvOut.x = vOut.y = vOut.z = 0;\n" << "\n" << "\t\tif (MwcNext01(mwc) < " << rootFace << ")\n" << "\t\t outPoint->m_Z = max(" << weight << ", (real_t)(0.0));\n" << "\t\telse\n" << "\t\t outPoint->m_Z = " << weight << " * MwcNext01(mwc);\n" << "\t}\n"; } else { ss << "\t{\n" << "\t\tvOut.x = vIn.x;\n" << "\t\tvOut.y = vIn.y;\n" << "\n" << "\t\tif (MwcNext01(mwc) < " << rootFace << ")\n" << "\t\t vOut.z = max(" << weight << ", (real_t)(0.0));\n" << "\t\telse\n" << "\t\t vOut.z = " << weight << " * MwcNext01(mwc);\n" << "\t}\n"; } return ss.str(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_RootFace, prefix + "extrude_root_face", T(0.5))); } private: T m_RootFace; }; /// /// fdisc. /// template class FDiscVariation : public Variation { public: FDiscVariation(T weight = 1.0) : Variation("fdisc", eVariationId::VAR_FDISC, weight, true, true, false, false, true) { } VARCOPY(FDiscVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T c, s; T a = M_2PI / (helper.m_PrecalcSqrtSumSquares + 1); T r = (helper.m_PrecalcAtanyx * T(M_1_PI) + 1) * T(0.5); sincos(a, &s, &c); helper.Out.x = m_Weight * r * c; helper.Out.y = m_Weight * r * s; helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t a = M_2PI / (precalcSqrtSumSquares + 1);\n" << "\t\treal_t r = fma(precalcAtanyx, M1PI, (real_t)(1.0)) * (real_t)(0.5);\n" << "\t\treal_t s = sin(a);\n" << "\t\treal_t c = cos(a);\n" << "\n" << "\t\tvOut.x = " << weight << " * r * c;\n" << "\t\tvOut.y = " << weight << " * r * s;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } }; /// /// Fibonacci. /// template class FibonacciVariation : public ParametricVariation { public: FibonacciVariation(T weight = 1.0) : ParametricVariation("fibonacci", eVariationId::VAR_FIBONACCI, weight) { Init(); } PARVARCOPY(FibonacciVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T snum1, cnum1, snum2, cnum2; T temp = helper.In.y * m_NatLog; sincos(temp, &snum1, &cnum1); temp = (helper.In.x * T(M_PI) + helper.In.y * m_NatLog) * -1; sincos(temp, &snum2, &cnum2); T eradius1 = std::exp(helper.In.x * m_NatLog); T eradius2 = std::exp((helper.In.x * m_NatLog - helper.In.y * T(M_PI)) * -1); helper.Out.x = m_Weight * (eradius1 * cnum1 - eradius2 * cnum2) * m_Five; helper.Out.y = m_Weight * (eradius1 * snum1 - eradius2 * snum2) * m_Five; 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 five = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. string natLog = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t temp = vIn.y * " << natLog << ";\n" << "\t\treal_t snum1 = sin(temp);\n" << "\t\treal_t cnum1 = cos(temp);\n" << "\t\ttemp = fma(vIn.x, MPI, vIn.y * " << natLog << ") * (real_t)(-1.0);\n" << "\t\treal_t snum2 = sin(temp);\n" << "\t\treal_t cnum2 = cos(temp);\n" << "\t\treal_t eradius1 = exp(vIn.x * " << natLog << ");\n" << "\t\treal_t eradius2 = exp(fma(vIn.x, " << natLog << ", -(vIn.y * MPI)) * (real_t)(-1.0));\n" << "\n" << "\t\tvOut.x = " << weight << " * (eradius1 * cnum1 - eradius2 * cnum2) * " << five << ";\n" << "\t\tvOut.y = " << weight << " * (eradius1 * snum1 - eradius2 * snum2) * " << five << ";\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Five = 1 / SQRT5; m_NatLog = std::log(M_PHI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_Five, prefix + "fibonacci_five"));//Precalcs only, no params. m_Params.push_back(ParamWithName(true, &m_NatLog, prefix + "fibonacci_nat_log")); } private: T m_Five;//Precalcs only, no params. T m_NatLog; }; /// /// Fibonacci2. /// template class Fibonacci2Variation : public ParametricVariation { public: Fibonacci2Variation(T weight = 1.0) : ParametricVariation("fibonacci2", eVariationId::VAR_FIBONACCI2, weight) { Init(); } PARVARCOPY(Fibonacci2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T snum1, cnum1, snum2, cnum2; T temp = helper.In.y * m_NatLog; sincos(temp, &snum1, &cnum1); temp = (helper.In.x * T(M_PI) + helper.In.y * m_NatLog) * -1; sincos(temp, &snum2, &cnum2); T eradius1 = m_Sc * std::exp(m_Sc2 * (helper.In.x * m_NatLog)); T eradius2 = m_Sc * std::exp(m_Sc2 * ((helper.In.x * m_NatLog - helper.In.y * T(M_PI)) * -1)); helper.Out.x = m_Weight * (eradius1 * cnum1 - eradius2 * cnum2) * m_Five; helper.Out.y = m_Weight * (eradius1 * snum1 - eradius2 * snum2) * m_Five; 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 sc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sc2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string five = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string natLog = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t temp = vIn.y * " << natLog << ";\n" << "\t\treal_t snum1 = sin(temp);\n" << "\t\treal_t cnum1 = cos(temp);\n" << "\t\ttemp = fma(vIn.x, MPI, vIn.y * " << natLog << ") * -1;\n" << "\t\treal_t snum2 = sin(temp);\n" << "\t\treal_t cnum2 = cos(temp);\n" << "\t\treal_t eradius1 = " << sc << " * exp(" << sc2 << " * (vIn.x * " << natLog << "));\n" << "\t\treal_t eradius2 = " << sc << " * exp(" << sc2 << " * (fma(vIn.x, " << natLog << ", -(vIn.y * MPI)) * (real_t)(-1.0)));\n" << "\n" << "\t\tvOut.x = " << weight << " * fma(eradius1, cnum1, -(eradius2 * cnum2)) * " << five << ";\n" << "\t\tvOut.y = " << weight << " * fma(eradius1, snum1, -(eradius2 * snum2)) * " << five << ";\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Five = 1 / SQRT5; m_NatLog = std::log(M_PHI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Sc, prefix + "fibonacci2_sc", 1)); m_Params.push_back(ParamWithName(&m_Sc2, prefix + "fibonacci2_sc2", 1)); m_Params.push_back(ParamWithName(true, &m_Five, prefix + "fibonacci2_five"));//Precalcs. m_Params.push_back(ParamWithName(true, &m_NatLog, prefix + "fibonacci2_nat_log")); } private: T m_Sc; T m_Sc2; T m_Five;//Precalcs. T m_NatLog; }; /// /// Glynnia. /// template class GlynniaVariation : public ParametricVariation { public: GlynniaVariation(T weight = 1.0) : ParametricVariation("glynnia", eVariationId::VAR_GLYNNIA, weight, true, true) { Init(); } PARVARCOPY(GlynniaVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T d, r = helper.m_PrecalcSqrtSumSquares; if (r > 1) { if (rand.Frand01() > T(0.5)) { d = std::sqrt(r + helper.In.x); helper.Out.x = m_V2 * d; helper.Out.y = -(m_V2 / d * helper.In.y); } else { d = r + helper.In.x; r = m_Weight / std::sqrt(r * (SQR(helper.In.y) + SQR(d))); helper.Out.x = r * d; helper.Out.y = r * helper.In.y; } } else { if (rand.Frand01() > T(0.5)) { d = Zeps(std::sqrt(r + helper.In.x)); helper.Out.x = -(m_V2 * d); helper.Out.y = -(m_V2 / d * helper.In.y); } else { d = r + helper.In.x; r = m_Weight / Zeps(std::sqrt(r * (SQR(helper.In.y) + SQR(d)))); helper.Out.x = -(r * d); helper.Out.y = r * helper.In.y; } } 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 v2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. ss << "\t{\n" << "\t\treal_t d, r = precalcSqrtSumSquares;\n" << "\n" << "\t\tif (r > 1)\n" << "\t\t{\n" << "\t\t if (MwcNext01(mwc) > (real_t)(0.5))\n" << "\t\t {\n" << "\t\t d = sqrt(r + vIn.x);\n" << "\t\t vOut.x = " << v2 << " * d;\n" << "\t\t vOut.y = -(" << v2 << " / d * vIn.y);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t d = r + vIn.x;\n" << "\t\t r = " << weight << " / sqrt(r * fma(vIn.y, vIn.y, SQR(d)));\n" << "\t\t vOut.x = r * d;\n" << "\t\t vOut.y = r * vIn.y;\n" << "\t\t }\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (MwcNext01(mwc) > (real_t)(0.5))\n" << "\t\t {\n" << "\t\t d = Zeps(sqrt(r + vIn.x));\n" << "\t\t vOut.x = -(" << v2 << " * d);\n" << "\t\t vOut.y = -(" << v2 << " / d * vIn.y);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t d = r + vIn.x;\n" << "\t\t r = " << weight << " / sqrt(r * fma(vIn.y, vIn.y, SQR(d)));\n" << "\t\t vOut.x = -(r * d);\n" << "\t\t vOut.y = r * vIn.y;\n" << "\t\t }\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_V2 = m_Weight * std::sqrt(T(2)) / 2; } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_V2, prefix + "glynnia_v2"));//Precalcs only, no params. } private: T m_V2;//Precalcs only, no params. }; /// /// Glynnia2. /// By guagapunyaimel. /// template class Glynnia2Variation : public ParametricVariation { public: Glynnia2Variation(T weight = 1.0) : ParametricVariation("glynnia2", eVariationId::VAR_GLYNNIA2, weight, true, true) { Init(); } PARVARCOPY(Glynnia2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T d, r = helper.m_PrecalcSqrtSumSquares; if (r > 0 && helper.In.y > 0) { if (rand.Frand01() > T(0.5)) { d = std::sqrt(r + helper.In.x); helper.Out.x = m_V2 * d; helper.Out.y = -(m_V2 / d * helper.In.y); } else { d = r + helper.In.x; r = m_Weight / std::sqrt(r * (SQR(helper.In.y) + SQR(d))); helper.Out.x = r * d; helper.Out.y = r * helper.In.y; } } else { if (rand.Frand01() > T(0.5)) { d = Zeps(std::sqrt(r + helper.In.x)); helper.Out.x = -(m_V2 * d); helper.Out.y = -(m_V2 / d * helper.In.y); } else { d = r + helper.In.x; r = m_Weight / Zeps(std::sqrt(r * (SQR(helper.In.y) + SQR(d)))); helper.Out.x = -(r * d); helper.Out.y = r * helper.In.y; } } 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 v2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. ss << "\t{\n" << "\t\treal_t d, r = precalcSqrtSumSquares;\n" << "\n" << "\t\tif (r > 0 && vIn.y > 0)\n" << "\t\t{\n" << "\t\t if (MwcNext01(mwc) > (real_t)(0.5))\n" << "\t\t {\n" << "\t\t d = sqrt(r + vIn.x);\n" << "\t\t vOut.x = " << v2 << " * d;\n" << "\t\t vOut.y = -(" << v2 << " / d * vIn.y);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t d = r + vIn.x;\n" << "\t\t r = " << weight << " / sqrt(r * fma(vIn.y, vIn.y, SQR(d)));\n" << "\t\t vOut.x = r * d;\n" << "\t\t vOut.y = r * vIn.y;\n" << "\t\t }\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (MwcNext01(mwc) > (real_t)(0.5))\n" << "\t\t {\n" << "\t\t d = Zeps(sqrt(r + vIn.x));\n" << "\t\t vOut.x = -(" << v2 << " * d);\n" << "\t\t vOut.y = -(" << v2 << " / d * vIn.y);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t d = r + vIn.x;\n" << "\t\t r = " << weight << " / Zeps(sqrt(r * fma(vIn.y, vIn.y, SQR(d))));\n" << "\t\t vOut.x = -(r * d);\n" << "\t\t vOut.y = r * vIn.y;\n" << "\t\t }\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_V2 = m_Weight * std::sqrt(T(2)) / 2; } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_V2, prefix + "glynnia2_v2"));//Precalcs only, no params. } private: T m_V2;//Precalcs only, no params. }; /// /// GridOut. /// template class GridOutVariation : public Variation { public: GridOutVariation(T weight = 1.0) : Variation("gridout", eVariationId::VAR_GRIDOUT, weight) { } VARCOPY(GridOutVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T x = VarFuncs::LRint(helper.In.x); T y = VarFuncs::LRint(helper.In.y); if (y <= 0) { if (x > 0) { if (-y >= x) { helper.Out.x = m_Weight * (helper.In.x + 1); helper.Out.y = m_Weight * helper.In.y; } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * (helper.In.y + 1); } } else { if (y <= x) { helper.Out.x = m_Weight * (helper.In.x + 1); helper.Out.y = m_Weight * helper.In.y; } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * (helper.In.y - 1); } } } else { if (x > 0) { if (y >= x) { helper.Out.x = m_Weight * (helper.In.x - 1); helper.Out.y = m_Weight * helper.In.y; } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * (helper.In.y + 1); } } else { if (y > -x) { helper.Out.x = m_Weight * (helper.In.x - 1); helper.Out.y = m_Weight * helper.In.y; } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * (helper.In.y - 1); } } } helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t x = LRint(vIn.x);\n" << "\t\treal_t y = LRint(vIn.y);\n" << "\n" << "\t\tif (y <= 0)\n" << "\t\t{\n" << "\t\t if (x > 0)\n" << "\t\t {\n" << "\t\t if (-y >= x)\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * (vIn.x + 1);\n" << "\t\t vOut.y = " << weight << " * vIn.y;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * vIn.x;\n" << "\t\t vOut.y = " << weight << " * (vIn.y + 1);\n" << "\t\t }\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t if (y <= x)\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * (vIn.x + 1);\n" << "\t\t vOut.y = " << weight << " * vIn.y;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * vIn.x;\n" << "\t\t vOut.y = " << weight << " * (vIn.y - 1);\n" << "\t\t }\n" << "\t\t }\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (x > 0)\n" << "\t\t {\n" << "\t\t if (y >= x)\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * (vIn.x - 1);\n" << "\t\t vOut.y = " << weight << " * vIn.y;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * vIn.x;\n" << "\t\t vOut.y = " << weight << " * (vIn.y + 1);\n" << "\t\t }\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t if (y > -x)\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * (vIn.x - 1);\n" << "\t\t vOut.y = " << weight << " * vIn.y;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.x = " << weight << " * vIn.x;\n" << "\t\t vOut.y = " << weight << " * (vIn.y - 1);\n" << "\t\t }\n" << "\t\t }\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "LRint" }; } }; /// /// Hole. /// template class HoleVariation : public ParametricVariation { public: HoleVariation(T weight = 1.0) : ParametricVariation("hole", eVariationId::VAR_HOLE, weight, true, true, true, false, true) { Init(); } PARVARCOPY(HoleVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r, delta = std::pow(helper.m_PrecalcAtanyx / T(M_PI) + 1, m_A); if (m_Inside != 0) r = m_Weight * delta / (helper.m_PrecalcSqrtSumSquares + delta); else r = m_Weight * helper.m_PrecalcSqrtSumSquares + delta; 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; string inside = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r, delta = pow(precalcAtanyx / MPI + 1, " << a << ");\n" << "\n" << "\t\tif (" << inside << " != 0)\n" << "\t\t r = " << weight << " * delta / (precalcSqrtSumSquares + delta);\n" << "\t\telse\n" << "\t\t r = fma(" << weight << ", precalcSqrtSumSquares, delta);\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 + "hole_a", 1)); m_Params.push_back(ParamWithName(&m_Inside, prefix + "hole_inside", 0, eParamType::INTEGER, 0, 1)); } private: T m_A; T m_Inside; }; /// /// Hypertile. /// template class HypertileVariation : public ParametricVariation { public: HypertileVariation(T weight = 1.0) : ParametricVariation("hypertile", eVariationId::VAR_HYPERTILE, weight) { Init(); } PARVARCOPY(HypertileVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = helper.In.x + m_Real; T b = helper.In.y - m_Imag; T c = m_Real * helper.In.x - m_Imag * helper.In.y + 1; T d = m_Real * helper.In.y + m_Imag * helper.In.x; T vr = m_Weight / (SQR(c) + SQR(d)); helper.Out.x = vr * (a * c + b * d); helper.Out.y = vr * (b * c - a * d); 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 p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string real = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string imag = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = vIn.x + " << real << ";\n" << "\t\treal_t b = vIn.y - " << imag << ";\n" << "\t\treal_t c = fma(" << real << ", vIn.x, -(" << imag << " * vIn.y)) + 1;\n" << "\t\treal_t d = fma(" << real << ", vIn.y, " << imag << " * vIn.x);\n" << "\t\treal_t vr = " << weight << " / fma(c, c, SQR(d));\n" << "\n" << "\t\tvOut.x = vr * fma(a, c, b * d);\n" << "\t\tvOut.y = vr * fma(b, c, -(a * d));\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { T pa = T(M_2PI) / Zeps(m_P); T cs = std::cos(pa); T r2 = (T(1) - cs) / (cs + cos(M_2PI / Zeps(m_Q))) + 1; T r = (r2 > 0) ? T(1) / sqrt(r2) : T(1); T a = m_N * pa; m_Real = r * std::cos(a); m_Imag = r * std::sin(a); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile_p", T(3))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile_q", T(7))); m_Params.push_back(ParamWithName(&m_N, prefix + "hypertile_n", T(0))); m_Params.push_back(ParamWithName(true, &m_Real, prefix + "hypertile_real"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Imag, prefix + "hypertile_imag")); } private: T m_P; T m_Q; T m_N; T m_Real;//Precalc. T m_Imag; }; /// /// Hypertile1. /// template class Hypertile1Variation : public ParametricVariation { public: Hypertile1Variation(T weight = 1.0) : ParametricVariation("hypertile1", eVariationId::VAR_HYPERTILE1, weight) { Init(); } PARVARCOPY(Hypertile1Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T temp = Floor(rand.Frand01() * m_IP) * m_Pa; T sina = std::sin(temp); T cosa = std::cos(temp); T re = m_R * cosa; T im = m_R * sina; T a = helper.In.x + re; T b = helper.In.y - im; T c = re * helper.In.x - im * helper.In.y + 1; T d = re * helper.In.y + im * helper.In.x; T vr = m_Weight / (SQR(c) + SQR(d)); helper.Out.x = vr * (a * c + b * d); helper.Out.y = vr * (b * c - a * d); 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 p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ip = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t temp = floor(MwcNext01(mwc) * " << ip << ") * " << pa << ";\n" << "\t\treal_t sina = sin(temp);\n" << "\t\treal_t cosa = cos(temp);\n" << "\t\treal_t re = " << r << " * cosa;\n" << "\t\treal_t im = " << r << " * sina;\n" << "\t\treal_t a = vIn.x + re;\n" << "\t\treal_t b = vIn.y - im;\n" << "\t\treal_t c = fma(re, vIn.x, -(im * vIn.y)) + 1;\n" << "\t\treal_t d = fma(re, vIn.y, im * vIn.x);\n" << "\t\treal_t vr = " << weight << " / fma(c, c, SQR(d));\n" << "\n" << "\t\tvOut.x = vr * fma(a, c, b * d);\n" << "\t\tvOut.y = vr * fma(b, c, -(a * d));\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Pa = T(M_2PI) / Zeps(m_P); T cs = cos(m_Pa); T r2 = T(1) - (cs - 1) / (cs + cos(M_2PI / Zeps(m_Q))); m_R = (r2 > 0) ? T(1) / sqrt(r2) : T(1); m_IP = (int) m_P; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile1_p", T(3))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile1_q", T(7))); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile1_pa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile1_r")); m_Params.push_back(ParamWithName(true, &m_IP, prefix + "hypertile1_ip")); } private: T m_P; T m_Q; T m_Pa;//Precalc. T m_R; T m_IP; }; /// /// Hypertile2. /// template class Hypertile2Variation : public ParametricVariation { public: Hypertile2Variation(T weight = 1.0) : ParametricVariation("hypertile2", eVariationId::VAR_HYPERTILE2, weight) { Init(); } PARVARCOPY(Hypertile2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = helper.In.x + m_R; T b = helper.In.y; T c = m_R * helper.In.x + 1; T d = m_R * helper.In.y; T x = (a * c + b * d); T y = (b * c - a * d); T vr = m_Weight / (SQR(c) + SQR(d)); T temp = Floor(rand.Frand01() * 32767) * m_Pa; T sina = std::sin(temp); T cosa = std::cos(temp); helper.Out.x = vr * (x * cosa + y * sina); helper.Out.y = vr * (y * cosa - x * sina); 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 p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = vIn.x + " << r << ";\n" << "\t\treal_t b = vIn.y;\n" << "\t\treal_t c = " << r << " * vIn.x + 1;\n" << "\t\treal_t d = " << r << " * vIn.y;\n" << "\t\treal_t x = fma(a, c, b * d);\n" << "\t\treal_t y = fma(b, c, -(a * d));\n" << "\t\treal_t vr = " << weight << " / fma(c, c, SQR(d));\n" << "\t\treal_t temp = floor(MwcNext01(mwc) * 32767) * " << pa << ";\n" << "\t\treal_t sina = sin(temp);\n" << "\t\treal_t cosa = cos(temp);\n" << "\n" << "\t\tvOut.x = vr * fma(x, cosa, y * sina);\n" << "\t\tvOut.y = vr * fma(y, cosa, -(x * sina));\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Pa = T(M_2PI) / Zeps(m_P); T cs = cos(m_Pa); T r2 = T(1) - (cs - T(1)) / (cs + cos(T(M_2PI) / Zeps(m_Q))); m_R = (r2 > 0) ? T(1) / sqrt(r2) : T(1); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile2_p", T(3))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile2_q", T(7))); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile2_pa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile2_r")); } private: T m_P; T m_Q; T m_Pa;//Precalc. T m_R; }; /// /// Hypertile3D. /// template class Hypertile3DVariation : public ParametricVariation { public: Hypertile3DVariation(T weight = 1.0) : ParametricVariation("hypertile3D", eVariationId::VAR_HYPERTILE3D, weight, true) { Init(); } PARVARCOPY(Hypertile3DVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r2 = helper.m_PrecalcSumSquares + helper.In.z; T x2cx = m_C2x * helper.In.x; T y2cy = m_C2y * helper.In.y; T d = m_Weight / Zeps(m_C2 * r2 + x2cx - y2cy + 1); helper.Out.x = d * (helper.In.x * m_S2x - m_Cx * (y2cy - r2 - 1)); helper.Out.y = d * (helper.In.y * m_S2y + m_Cy * (-x2cx - r2 - 1)); helper.Out.z = d * (helper.In.z * m_S2z); } virtual string OpenCLString() const override { ostringstream ss, ss2; intmax_t i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string n = "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 cz = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2z = "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; string c2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r2 = precalcSumSquares + vIn.z;\n" << "\t\treal_t x2cx = " << c2x << " * vIn.x;\n" << "\t\treal_t y2cy = " << c2y << " * vIn.y;\n" << "\t\treal_t d = " << weight << " / Zeps(fma(" << c2 << ", r2, (x2cx - y2cy) + 1));\n" << "\n" << "\t\tvOut.x = d * fma(vIn.x, " << s2x << ", -(" << cx << " * (y2cy - r2 - 1)));\n" << "\t\tvOut.y = d * fma(vIn.y, " << s2y << ", " << cy << " * (-x2cx - r2 - 1));\n" << "\t\tvOut.z = d * (vIn.z * " << s2z << ");\n" << "\t}\n"; return ss.str(); } virtual void Precalc() override { T pa = 2 * T(M_PI) / Zeps(m_P); T qa = 2 * T(M_PI) / Zeps(m_Q); T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); T na = m_N * pa; if (r > 0) r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; m_Cx = r * std::cos(na); m_Cy = r * std::sin(na); m_C2 = SQR(m_Cx) + SQR(m_Cy); m_C2x = 2 * m_Cx; m_C2y = 2 * m_Cy; m_S2x = 1 + SQR(m_Cx) - SQR(m_Cy); m_S2y = 1 + SQR(m_Cy) - SQR(m_Cx); m_S2z = 1 - SQR(m_Cy) - SQR(m_Cx); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile3D_p", 3, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile3D_q", 7, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(&m_N, prefix + "hypertile3D_n", 0, eParamType::INTEGER)); m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "hypertile3D_cx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cy, prefix + "hypertile3D_cy")); m_Params.push_back(ParamWithName(true, &m_Cz, prefix + "hypertile3D_cz")); m_Params.push_back(ParamWithName(true, &m_S2x, prefix + "hypertile3D_s2x")); m_Params.push_back(ParamWithName(true, &m_S2y, prefix + "hypertile3D_s2y")); m_Params.push_back(ParamWithName(true, &m_S2z, prefix + "hypertile3D_s2z")); m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "hypertile3D_c2x")); m_Params.push_back(ParamWithName(true, &m_C2y, prefix + "hypertile3D_c2y")); m_Params.push_back(ParamWithName(true, &m_C2z, prefix + "hypertile3D_c2z")); m_Params.push_back(ParamWithName(true, &m_C2, prefix + "hypertile3D_c2")); } private: T m_P; T m_Q; T m_N; T m_Cx;//Precalc. T m_Cy; T m_Cz; T m_S2x; T m_S2y; T m_S2z; T m_C2x; T m_C2y; T m_C2z; T m_C2; }; /// /// Hypertile3D1. /// template class Hypertile3D1Variation : public ParametricVariation { public: Hypertile3D1Variation(T weight = 1.0) : ParametricVariation("hypertile3D1", eVariationId::VAR_HYPERTILE3D1, weight, true) { Init(); } PARVARCOPY(Hypertile3D1Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T temp = rand.Rand() * m_Pa; T cx = m_R * std::cos(temp); T cy = m_R * std::sin(temp); T s2x = 1 + SQR(cx) - SQR(cy); T s2y = 1 + SQR(cy) - SQR(cx); T r2 = helper.m_PrecalcSumSquares + SQR(helper.In.z); T x2cx = 2 * cx * helper.In.x; T y2cy = 2 * cy * helper.In.x; T d = m_Weight / Zeps(m_C2 * r2 + x2cx - y2cy + 1); helper.Out.x = d * (helper.In.x * s2x - cx * (y2cy - r2 - 1)); helper.Out.y = d * (helper.In.y * s2y + cy * (-x2cx - r2 - 1)); helper.Out.z = d * (helper.In.z * m_S2z); } virtual string OpenCLString() const override { ostringstream ss, ss2; intmax_t i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2z = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t temp = MwcNext(mwc) * " << pa << ";\n" << "\t\treal_t cx = " << r << " * cos(temp);\n" << "\t\treal_t cy = " << r << " * sin(temp);\n" << "\t\treal_t s2x = fma(cx, cx, (real_t)(1.0)) - SQR(cy);\n" << "\t\treal_t s2y = fma(cy, cy, (real_t)(1.0)) - SQR(cx);\n" << "\t\treal_t r2 = precalcSumSquares + SQR(vIn.z);\n" << "\t\treal_t x2cx = 2 * cx * vIn.x;\n" << "\t\treal_t y2cy = 2 * cy * vIn.x;\n" << "\t\treal_t d = " << weight << " / Zeps(fma(" << c2 << ", r2, (x2cx - y2cy) + 1)); \n" << "\n" << "\t\tvOut.x = d * fma(vIn.x, s2x, -(cx * (y2cy - r2 - 1)));\n" << "\t\tvOut.y = d * fma(vIn.y, s2y, cy * (-x2cx - r2 - 1));\n" << "\t\tvOut.z = d * (vIn.z * " << s2z << ");\n" << "\t}\n"; return ss.str(); } virtual void Precalc() override { T pa = M_2PI / Zeps(m_P); T qa = M_2PI / Zeps(m_Q); T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); if (r > 0) r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; m_Pa = pa; m_R = r; m_C2 = SQR(r); m_S2z = 1 - m_C2; } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile3D1_p", 3, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile3D1_q", 7, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile3D1_pa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile3D1_r")); m_Params.push_back(ParamWithName(true, &m_C2, prefix + "hypertile3D1_c2")); m_Params.push_back(ParamWithName(true, &m_S2z, prefix + "hypertile3D1_s2z")); } private: T m_P; T m_Q; T m_Pa;//Precalc. T m_R; T m_C2; T m_S2z; }; /// /// Hypertile3D2. /// template class Hypertile3D2Variation : public ParametricVariation { public: Hypertile3D2Variation(T weight = 1.0) : ParametricVariation("hypertile3D2", eVariationId::VAR_HYPERTILE3D2, weight, true) { Init(); } PARVARCOPY(Hypertile3D2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r2 = helper.m_PrecalcSumSquares + SQR(helper.In.z); T x2cx = m_C2x * helper.In.x; T x = helper.In.x * m_S2x - m_Cx * (-r2 - 1); T y = helper.In.y * m_S2y; T vr = m_Weight / (m_C2 * r2 + x2cx + 1); T temp = rand.Rand() * m_Pa; T sina = std::sin(temp); T cosa = std::cos(temp); helper.Out.x = vr * (x * cosa + y * sina); helper.Out.y = vr * (y * cosa - x * sina); helper.Out.z = vr * (helper.In.z * m_S2z); } virtual string OpenCLString() const override { ostringstream ss, ss2; intmax_t i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cx = "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 s2x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2z = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r2 = precalcSumSquares + SQR(vIn.z);\n" << "\t\treal_t x2cx = " << c2x << " * vIn.x;\n" << "\t\treal_t x = fma(vIn.x, " << s2x << ", -(" << cx << " * (-r2 - (real_t)(1.0))));\n" << "\t\treal_t y = vIn.y * " << s2y << ";\n" << "\t\treal_t vr = " << weight << " / fma(" << c2 << ", r2, x2cx + (real_t)(1.0));\n" << "\t\treal_t temp = MwcNext(mwc) * " << pa << ";\n" << "\t\treal_t sina = sin(temp);\n" << "\t\treal_t cosa = cos(temp);\n" << "\n" << "\t\tvOut.x = vr * fma(x, cosa, y * sina);\n" << "\t\tvOut.y = vr * fma(y, cosa, -(x * sina));\n" << "\t\tvOut.z = vr * (vIn.z * " << s2z << ");\n" << "\t}\n"; return ss.str(); } virtual void Precalc() override { T pa = M_2PI / Zeps(m_P); T qa = M_2PI / Zeps(m_Q); T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); if (r > 0) r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; m_Pa = pa; m_Cx = r; m_C2 = SQR(m_Cx); m_C2x = 2 * m_Cx; m_S2x = 1 + SQR(m_Cx); m_S2y = 1 - SQR(m_Cx); m_S2z = 1 - SQR(m_Cx); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile3D2_p", 3, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile3D2_q", 7, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile3D2_pa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "hypertile3D2_cx")); m_Params.push_back(ParamWithName(true, &m_C2, prefix + "hypertile3D2_c2")); m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "hypertile3D2_c2x")); m_Params.push_back(ParamWithName(true, &m_S2x, prefix + "hypertile3D2_s2x")); m_Params.push_back(ParamWithName(true, &m_S2y, prefix + "hypertile3D2_s2y")); m_Params.push_back(ParamWithName(true, &m_S2z, prefix + "hypertile3D2_s2z")); } private: T m_P; T m_Q; T m_Pa;//Precalc. T m_Cx; T m_C2; T m_C2x; T m_S2x; T m_S2y; T m_S2z; }; /// /// IDisc. /// template class IDiscVariation : public ParametricVariation { public: IDiscVariation(T weight = 1.0) : ParametricVariation("idisc", eVariationId::VAR_IDISC, weight, true, true, false, false, true) { Init(); } PARVARCOPY(IDiscVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = T(M_PI) / (helper.m_PrecalcSqrtSumSquares + 1); T s = std::sin(a); T c = std::cos(a); T r = helper.m_PrecalcAtanyx * m_V; helper.Out.x = r * c; helper.Out.y = r * s; 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\treal_t a = MPI / (precalcSqrtSumSquares + 1);\n" << "\t\treal_t s = sin(a);\n" << "\t\treal_t c = cos(a);\n" << "\t\treal_t r = precalcAtanyx * " << v << ";\n" << "\n" << "\t\tvOut.x = r * c;\n" << "\t\tvOut.y = r * s;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_V = m_Weight * T(M_1_PI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_V, prefix + "idisc_v"));//Precalcs only, no params. } private: T m_V;//Precalcs only, no params. }; /// /// Julian2. /// template class Julian2Variation : public ParametricVariation { public: Julian2Variation(T weight = 1.0) : ParametricVariation("julian2", eVariationId::VAR_JULIAN2, weight) { Init(); } PARVARCOPY(Julian2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T x = m_A * helper.In.x + m_B * helper.In.y + m_E; T y = m_C * helper.In.x + m_D * helper.In.y + m_F; T angle = (std::atan2(y, x) + M_2PI * rand.Rand(int(m_AbsN))) / m_Power; T sina = std::sin(angle); T cosa = std::cos(angle); T r = m_Weight * std::pow(SQR(x) + SQR(y), m_Cn); helper.Out.x = r * cosa; helper.Out.y = r * sina; 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; string b = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string e = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string f = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string absn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = fma(" << a << ", vIn.x, fma(" << b << ", vIn.y, " << e << "));\n" << "\t\treal_t y = fma(" << c << ", vIn.x, fma(" << d << ", vIn.y, " << f << "));\n" << "\t\treal_t angle = fma(M_2PI, (real_t)MwcNextRange(mwc, (uint)" << absn << "), atan2(y, x)) / " << power << ";\n" << "\t\treal_t sina = sin(angle);\n" << "\t\treal_t cosa = cos(angle);\n" << "\t\treal_t r = " << weight << " * pow(fma(x, x, SQR(y)), " << cn << ");\n" << "\n" << "\t\tvOut.x = r * cosa;\n" << "\t\tvOut.y = r * sina;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { if (m_Power == 0) m_Power = 2; m_AbsN = T(int(abs(m_Power))); m_Cn = m_Dist / m_Power / 2; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_A, prefix + "julian2_a", 1)); m_Params.push_back(ParamWithName(&m_B, prefix + "julian2_b")); m_Params.push_back(ParamWithName(&m_C, prefix + "julian2_c")); m_Params.push_back(ParamWithName(&m_D, prefix + "julian2_d", 1)); m_Params.push_back(ParamWithName(&m_E, prefix + "julian2_e")); m_Params.push_back(ParamWithName(&m_F, prefix + "julian2_f")); m_Params.push_back(ParamWithName(&m_Power, prefix + "julian2_power", 2, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(&m_Dist, prefix + "julian2_dist", 1)); m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "julian2_absn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "julian2_cn")); } private: T m_A; T m_B; T m_C; T m_D; T m_E; T m_F; T m_Power; T m_Dist; T m_AbsN;//Precalc. T m_Cn; }; /// /// JuliaQ. /// template class JuliaQVariation : public ParametricVariation { public: JuliaQVariation(T weight = 1.0) : ParametricVariation("juliaq", eVariationId::VAR_JULIAQ, weight, true, false, false, false, true) { Init(); } PARVARCOPY(JuliaQVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = helper.m_PrecalcAtanyx * m_InvPower + rand.Rand() * m_InvPower2pi; T sina = std::sin(a); T cosa = std::cos(a); T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_HalfInvPower); helper.Out.x = r * cosa; helper.Out.y = r * sina; 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 power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string divisor = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string halfInvPower = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string invPower = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string invPower2Pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = fma(precalcAtanyx, " << invPower << ", MwcNext(mwc) * " << invPower2Pi << ");\n" << "\t\treal_t sina = sin(a);\n" << "\t\treal_t cosa = cos(a);\n" << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << halfInvPower << ");\n" << "\n" << "\t\tvOut.x = r * cosa;\n" << "\t\tvOut.y = r * sina;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_HalfInvPower = T(0.5) * m_Divisor / m_Power; m_InvPower = m_Divisor / m_Power; m_InvPower2pi = M_2PI / m_Power; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Power, prefix + "juliaq_power", 3, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(&m_Divisor, prefix + "juliaq_divisor", 2, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(true, &m_HalfInvPower, prefix + "juliaq_half_inv_power"));//Precalc. m_Params.push_back(ParamWithName(true, &m_InvPower, prefix + "juliaq_inv_power")); m_Params.push_back(ParamWithName(true, &m_InvPower2pi, prefix + "juliaq_inv_power_2pi")); } private: T m_Power; T m_Divisor; T m_HalfInvPower;//Precalc. T m_InvPower; T m_InvPower2pi; }; /// /// Murl. /// template class MurlVariation : public ParametricVariation { public: MurlVariation(T weight = 1.0) : ParametricVariation("murl", eVariationId::VAR_MURL, weight, true, false, false, false, true) { Init(); } PARVARCOPY(MurlVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T angle = helper.m_PrecalcAtanyx * m_Power; T sina = std::sin(angle); T cosa = std::cos(angle); T r = m_Cp * std::pow(helper.m_PrecalcSumSquares, m_P2); T re = r * cosa + 1; T im = r * sina; T r1 = m_Vp / (SQR(re) + SQR(im)); helper.Out.x = r1 * (helper.In.x * re + helper.In.y * im); helper.Out.y = r1 * (helper.In.y * re - helper.In.x * im); 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 c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string p2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t angle = precalcAtanyx * " << power << ";\n" << "\t\treal_t sina = sin(angle);\n" << "\t\treal_t cosa = cos(angle);\n" << "\t\treal_t r = " << cp << " * pow(precalcSumSquares, " << p2 << ");\n" << "\t\treal_t re = fma(r, cosa, (real_t)(1.0));\n" << "\t\treal_t im = r * sina;\n" << "\t\treal_t r1 = " << vp << " / fma(re, re, SQR(im));\n" << "\n" << "\t\tvOut.x = r1 * fma(vIn.x, re, vIn.y * im);\n" << "\t\tvOut.y = r1 * fma(vIn.y, re, -(vIn.x * im));\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { if (m_Power != 1) m_Cp = m_C / (m_Power - 1); else m_Cp = m_C; m_P2 = m_Power / 2; m_Vp = m_Weight * (m_Cp + 1); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_C, prefix + "murl_c")); m_Params.push_back(ParamWithName(&m_Power, prefix + "murl_power", 2, eParamType::INTEGER, 2, T(0x7fffffff))); m_Params.push_back(ParamWithName(true, &m_Cp, prefix + "murl_cp"));//Precalc. m_Params.push_back(ParamWithName(true, &m_P2, prefix + "murl_p2")); m_Params.push_back(ParamWithName(true, &m_Vp, prefix + "murl_vp")); } private: T m_C; T m_Power; T m_Cp;//Precalc. T m_P2; T m_Vp; }; /// /// Murl2. /// template class Murl2Variation : public ParametricVariation { public: Murl2Variation(T weight = 1.0) : ParametricVariation("murl2", eVariationId::VAR_MURL2, weight, true, false, false, false, true) { Init(); } PARVARCOPY(Murl2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T angle = helper.m_PrecalcAtanyx * m_Power; T sina = std::sin(angle); T cosa = std::cos(angle); T r = m_C * std::pow(helper.m_PrecalcSumSquares, m_P2); T re = r * cosa + 1; T im = r * sina; r = std::pow(SQR(re) + SQR(im), m_InvP); angle = std::atan2(im, re) * m_InvP2; sina = std::sin(angle); cosa = std::cos(angle); re = r * cosa; im = r * sina; T r1 = m_Vp / SQR(r); helper.Out.x = r1 * (helper.In.x * re + helper.In.y * im); helper.Out.y = r1 * (helper.In.y * re - helper.In.x * im); 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 c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string p2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string invp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string invp2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t angle = precalcAtanyx * " << power << ";\n" << "\t\treal_t sina = sin(angle);\n" << "\t\treal_t cosa = cos(angle);\n" << "\t\treal_t r = " << c << " * pow(precalcSumSquares, " << p2 << ");\n" << "\t\treal_t re = fma(r, cosa, (real_t)(1.0));\n" << "\t\treal_t im = r * sina;\n" << "\n" << "\t\tr = pow(fma(re, re, SQR(im)), " << invp << ");\n" << "\t\tangle = atan2(im, re) * " << invp2 << ";\n" << "\t\tsina = sin(angle);\n" << "\t\tcosa = cos(angle);\n" << "\t\tre = r * cosa;\n" << "\t\tim = r * sina;\n" << "\n" << "\t\treal_t r1 = " << vp << " / SQR(r);\n" << "\n" << "\t\tvOut.x = r1 * fma(vIn.x, re, vIn.y * im);\n" << "\t\tvOut.y = r1 * fma(vIn.y, re, -(vIn.x * im));\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_P2 = m_Power / 2; m_InvP = 1 / m_Power; m_InvP2 = 2 / m_Power; if (m_C == -1) m_Vp = 0; else m_Vp = m_Weight * std::pow(m_C + 1, 2 / m_Power); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_C, prefix + "murl2_c", 0, eParamType::REAL, -1, 1)); m_Params.push_back(ParamWithName(&m_Power, prefix + "murl2_power", 1, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(true, &m_P2, prefix + "murl2_p2"));//Precalc. m_Params.push_back(ParamWithName(true, &m_InvP, prefix + "murl2_invp")); m_Params.push_back(ParamWithName(true, &m_InvP2, prefix + "murl2_invp2")); m_Params.push_back(ParamWithName(true, &m_Vp, prefix + "murl2_vp")); } private: T m_C; T m_Power; T m_P2;//Precalc. T m_InvP; T m_InvP2; T m_Vp; }; /// /// NPolar. /// template class NPolarVariation : public ParametricVariation { public: NPolarVariation(T weight = 1.0) : ParametricVariation("npolar", eVariationId::VAR_NPOLAR, weight, true, false, false, true, false) { Init(); } PARVARCOPY(NPolarVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T x = (m_IsOdd != 0) ? helper.In.x : m_Vvar * helper.m_PrecalcAtanxy; T y = (m_IsOdd != 0) ? helper.In.y : m_Vvar2 * std::log(helper.m_PrecalcSumSquares); T angle = (std::atan2(y, x) + M_2PI * rand.Rand(int(m_AbsN))) / m_Nnz; T r = m_Weight * std::pow(SQR(x) + SQR(y), m_Cn) * ((m_IsOdd == 0) ? 1 : m_Parity); T sina = std::sin(angle) * r; T cosa = std::cos(angle) * r; x = (m_IsOdd != 0) ? cosa : (m_Vvar2 * std::log(SQR(cosa) + SQR(sina))); y = (m_IsOdd != 0) ? sina : (m_Vvar * std::atan2(cosa, sina)); helper.Out.x = x; helper.Out.y = y; 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 parity = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string nnz = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vvar = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vvar2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string absn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string isOdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = (" << isOdd << " != 0) ? vIn.x : " << vvar << " * precalcAtanxy;\n" << "\t\treal_t y = (" << isOdd << " != 0) ? vIn.y : " << vvar2 << " * log(precalcSumSquares);\n" << "\t\treal_t angle = fma(M_2PI, MwcNextRange(mwc, (uint)" << absn << "), atan2(y, x)) / " << nnz << ";\n" << "\t\treal_t r = " << weight << " * pow(fma(x, x, SQR(y)), " << cn << ") * ((" << isOdd << " == 0) ? 1 : " << parity << ");\n" << "\t\treal_t sina = sin(angle) * r;\n" << "\t\treal_t cosa = cos(angle) * r;\n" << "\n" << "\t\tx = (" << isOdd << " != 0) ? cosa : (" << vvar2 << " * log(fma(cosa, cosa, SQR(sina))));\n" << "\t\ty = (" << isOdd << " != 0) ? sina : (" << vvar << " * atan2(cosa, sina));\n" << "\t\tvOut.x = x;\n" << "\t\tvOut.y = y;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Nnz = (m_N == 0) ? 1 : m_N; m_Vvar = m_Weight / T(M_PI); m_Vvar2 = m_Vvar * T(0.5); m_AbsN = abs(m_Nnz); m_Cn = 1 / m_Nnz / 2; m_IsOdd = T(abs(int(m_Parity)) & 1); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Parity, prefix + "npolar_parity", 0, eParamType::INTEGER)); m_Params.push_back(ParamWithName(&m_N, prefix + "npolar_n", 1, eParamType::INTEGER)); m_Params.push_back(ParamWithName(true, &m_Nnz, prefix + "npolar_nnz"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Vvar, prefix + "npolar_vvar")); m_Params.push_back(ParamWithName(true, &m_Vvar2, prefix + "npolar_vvar_2")); m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "npolar_absn")); m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "npolar_cn")); m_Params.push_back(ParamWithName(true, &m_IsOdd, prefix + "npolar_isodd")); } private: T m_Parity; T m_N; T m_Nnz;//Precalc. T m_Vvar; T m_Vvar2; T m_AbsN; T m_Cn; T m_IsOdd; }; /// /// Ortho. /// template class OrthoVariation : public ParametricVariation { public: OrthoVariation(T weight = 1.0) : ParametricVariation("ortho", eVariationId::VAR_ORTHO, weight, true, false, false, false, true) { Init(); } PARVARCOPY(OrthoVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r, a; T xo; T ro; T c, s; T x, y, tc, ts; T theta; r = helper.m_PrecalcSumSquares; if (r < 1) { if (helper.In.x >= 0) { xo = (r + 1) / Zeps(2 * helper.In.x); ro = std::sqrt(Sqr(helper.In.x - xo) + SQR(helper.In.y)); theta = std::atan2(T(1), ro); a = fmod(m_In * theta + std::atan2(helper.In.y, xo - helper.In.x) + theta, 2 * theta) - theta; sincos(a, &s, &c); helper.Out.x = m_Weight * (xo - c * ro); helper.Out.y = m_Weight * s * ro; } else { xo = -(r + 1) / (2 * helper.In.x); ro = std::sqrt(Sqr(-helper.In.x - xo) + SQR(helper.In.y)); theta = std::atan2(T(1), ro); a = fmod(m_In * theta + std::atan2(helper.In.y, xo + helper.In.x) + theta, 2 * theta) - theta; sincos(a, &s, &c); helper.Out.x = -(m_Weight * (xo - c * ro)); helper.Out.y = m_Weight * s * ro; } } else { r = 1 / std::sqrt(r); ts = std::sin(helper.m_PrecalcAtanyx); tc = std::cos(helper.m_PrecalcAtanyx); x = r * tc; y = r * ts; if (x >= 0) { xo = (SQR(x) + SQR(y) + 1) / Zeps(2 * x); ro = std::sqrt(Sqr(x - xo) + SQR(y)); theta = std::atan2(T(1), ro); a = fmod(m_Out * theta + std::atan2(y, xo - x) + theta, 2 * theta) - theta; sincos(a, &s, &c); x = (xo - c * ro); y = s * ro; theta = std::atan2(y, x); sincos(theta, &ts, &tc); r = 1 / std::sqrt(SQR(x) + SQR(y)); helper.Out.x = m_Weight * r * tc; helper.Out.y = m_Weight * r * ts; } else { xo = -(SQR(x) + SQR(y) + 1) / (2 * x); ro = std::sqrt(Sqr(-x - xo) + SQR(y)); theta = std::atan2(T(1), ro); a = fmod(m_Out * theta + std::atan2(y, xo + x) + theta, 2 * theta) - theta; sincos(a, &s, &c); x = (xo - c * ro); y = s * ro; theta = std::atan2(y, x); sincos(theta, &ts, &tc); r = 1 / std::sqrt(SQR(x) + SQR(y)); helper.Out.x = -(m_Weight * r * tc); helper.Out.y = m_Weight * r * ts; } } 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 in = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string out = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r, a;\n" << "\t\treal_t xo;\n" << "\t\treal_t ro;\n" << "\t\treal_t c,s;\n" << "\t\treal_t x, y, tc, ts;\n" << "\t\treal_t theta;\n" << "\n" << "\t\tr = precalcSumSquares;\n" << "\n" << "\t\tif (r < 1)\n" << "\t\t{\n" << "\t\t real_t y2 = SQR(vIn.y);\n" << "\t\t if (vIn.x >= 0)\n" << "\t\t {\n" << "\t\t xo = (r + 1) / Zeps(2 * vIn.x);\n" << "\t\t real_t xmx = vIn.x - xo;\n" << "\t\t ro = sqrt(fma(xmx, xmx, y2));\n" << "\t\t theta = atan2(1, ro);\n" << "\t\t a = fmod(fma(" << in << ", theta, atan2(vIn.y, xo - vIn.x) + theta), 2 * theta) - theta;\n" << "\t\t s = sin(a);\n" << "\t\t c = cos(a);\n" << "\n" << "\t\t vOut.x = " << weight << " * (xo - c * ro);\n" << "\t\t vOut.y = " << weight << " * s * ro;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t xo = - (r + 1) / (2 * vIn.x);\n" << "\t\t real_t mxmx = -vIn.x - xo;\n" << "\t\t ro = sqrt(fma(mxmx, mxmx, y2));\n" << "\t\t theta = atan2(1 , ro);\n" << "\t\t a = fmod(fma(" << in << ", theta, atan2(vIn.y, xo + vIn.x) + theta), 2 * theta) - theta;\n" << "\t\t s = sin(a);\n" << "\t\t c = cos(a);\n" << "\n" << "\t\t vOut.x = -(" << weight << " * (xo - c * ro));\n" << "\t\t vOut.y = " << weight << " * s * ro;\n" << "\t\t }\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t r = 1 / sqrt(r);\n" << "\t\t ts = sin(precalcAtanyx);\n" << "\t\t tc = cos(precalcAtanyx);\n" << "\t\t x = r * tc;\n" << "\t\t y = r * ts;\n" << "\t\t real_t x2 = SQR(x);\n" << "\t\t real_t y2 = SQR(y);\n" << "\t\t real_t x2y2 = x2 + y2;\n" << "\n" << "\t\t if (x >= 0)\n" << "\t\t {\n" << "\t\t xo = (x2y2 + 1) / Zeps(2 * x);\n" << "\t\t real_t xmx = x - xo;\n" << "\t\t ro = sqrt(fma(xmx, xmx, y2));\n" << "\t\t theta = atan2(1, ro);\n" << "\t\t a = fmod(fma(" << out << ", theta, atan2(y, xo - x) + theta), 2 * theta) - theta;\n" << "\t\t s = sin(a);\n" << "\t\t c = cos(a);\n" << "\n" << "\t\t x = (xo - c * ro);\n" << "\t\t y = s * ro;\n" << "\t\t theta = atan2(y, x);\n" << "\t\t ts = sin(theta);\n" << "\t\t tc = cos(theta);\n" << "\t\t r = 1 / sqrt(fma(x, x, SQR(y)));\n" << "\n" << "\t\t vOut.x = " << weight << " * r * tc;\n" << "\t\t vOut.y = " << weight << " * r * ts;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t xo = -(x2y2 + 1) / (2 * x);\n" << "\t\t real_t mxmx = -x - xo;\n" << "\t\t ro = sqrt(fma(mxmx, mxmx, y2));\n" << "\t\t theta = atan2(1 , ro);\n" << "\t\t a = fmod(fma(" << out << ", theta, atan2(y, xo + x) + theta), 2 * theta) - theta;\n" << "\t\t s = sin(a);\n" << "\t\t c = cos(a);\n" << "\n" << "\t\t x = (xo - c * ro);\n" << "\t\t y = s * ro;\n" << "\t\t theta = atan2(y, x);\n" << "\t\t ts = sin(theta);\n" << "\t\t tc = cos(theta);\n" << "\t\t r = 1 / sqrt(fma(x, x, SQR(y)));\n" << "\n" << "\t\t vOut.x = -(" << weight << " * r * tc);\n" << "\t\t vOut.y = " << weight << " * r * ts;\n" << "\t\t }\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\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_In, prefix + "ortho_in", 0, eParamType::REAL_CYCLIC, T(-M_PI), T(M_PI))); m_Params.push_back(ParamWithName(&m_Out, prefix + "ortho_out", 0, eParamType::REAL_CYCLIC, T(-M_PI), T(M_PI))); } private: T m_In; T m_Out; }; /// /// Poincare. /// template class PoincareVariation : public ParametricVariation { public: PoincareVariation(T weight = 1.0) : ParametricVariation("poincare", eVariationId::VAR_POINCARE, weight) { Init(); } PARVARCOPY(PoincareVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T xmc1x = helper.In.x - m_C1x; T ymc1y = helper.In.y - m_C1y; T den = Zeps(SQR(xmc1x) + SQR(ymc1y)); T c1r2 = SQR(m_C1r); T x = m_C1x + (c1r2 * xmc1x) / den; T y = m_C1y + (c1r2 * ymc1y) / den; T xmc2x = x - m_C2x; T ymc2y = y - m_C2y; T c2r2 = SQR(m_C2r); den = Zeps(SQR(xmc2x) + SQR(ymc2y)); helper.Out.x = m_C2x + (c2r2 * xmc2x) / den; helper.Out.y = m_C2y + (c2r2 * ymc2y) / den; 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 c1r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c1a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c1x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c1y = "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 c1d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t xmc1x = vIn.x - " << c1x << ";\n" << "\t\treal_t ymc1y = vIn.y - " << c1y << ";\n" << "\t\treal_t den = Zeps(fma(xmc1x, xmc1x, SQR(ymc1y)));\n" << "\t\treal_t c1r2 = SQR(" << c1r << ");\n" << "\t\treal_t x = " << c1x << " + (c1r2 * xmc1x) / den;\n" << "\t\treal_t y = " << c1y << " + (c1r2 * ymc1y) / den;\n" << "\n" << "\t\treal_t xmc2x = x - " << c2x << ";\n" << "\t\treal_t ymc2y = y - " << c2y << ";\n" << "\t\treal_t c2r2 = SQR(" << c2r << ");\n" << "\t\tden = Zeps(fma(xmc2x, xmc2x, SQR(ymc2y)));\n" << "\t\tvOut.x = " << c2x << " + (c2r2 * xmc2x) / den;\n" << "\t\tvOut.y = " << c2y << " + (c2r2 * ymc2y) / den;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_C1d = std::sqrt(1 + SQR(m_C1r)); m_C2d = std::sqrt(1 + SQR(m_C2r)); m_C1x = m_C1d * std::cos(fmod(m_C1a, T(M_PI))); m_C1y = m_C1d * std::sin(fmod(m_C1a, T(M_PI))); m_C2x = m_C2d * std::cos(fmod(m_C2a, T(M_PI))); m_C2y = m_C2d * std::sin(fmod(m_C2a, T(M_PI))); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_C1r, prefix + "poincare_c1r", 1)); m_Params.push_back(ParamWithName(&m_C1a, prefix + "poincare_c1a", -1, eParamType::REAL_CYCLIC, T(-M_PI), T(M_PI))); m_Params.push_back(ParamWithName(&m_C2r, prefix + "poincare_c2r", 1)); m_Params.push_back(ParamWithName(&m_C2a, prefix + "poincare_c2a", 1, eParamType::REAL_CYCLIC, T(-M_PI), T(M_PI))); m_Params.push_back(ParamWithName(true, &m_C1x, prefix + "poincare_c1x"));//Precalc. m_Params.push_back(ParamWithName(true, &m_C1y, prefix + "poincare_c1y")); m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "poincare_c2x")); m_Params.push_back(ParamWithName(true, &m_C2y, prefix + "poincare_c2y")); m_Params.push_back(ParamWithName(true, &m_C1d, prefix + "poincare_c1d")); m_Params.push_back(ParamWithName(true, &m_C2d, prefix + "poincare_c2d")); } private: T m_C1r; T m_C1a; T m_C2r; T m_C2a; T m_C1x;//Precalc. T m_C1y; T m_C2x; T m_C2y; T m_C1d; T m_C2d; }; /// /// Poincare2. /// This is intended to mimic the Poincare variation in Chaotica. But we couldn't use the same name because /// Poincare already exists above. /// template class Poincare2Variation : public ParametricVariation { public: Poincare2Variation(T weight = 1.0) : ParametricVariation("poincare2", eVariationId::VAR_POINCARE2, weight) { Init(); } PARVARCOPY(Poincare2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = helper.In.x - m_Cx; T b = helper.In.y - m_Cy; T c = 1 - m_Cx * helper.In.x - m_Cy * helper.In.y; T d = m_Cy * helper.In.x - m_Cx * helper.In.y; T num = m_Weight / Zeps(c * c + d * d); helper.Out.x = (a * c + b * d) * num; helper.Out.y = (b * c - a * d) * num; 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 cP = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cQ = "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; ss << "\t{\n" << "\t\treal_t a = vIn.x - " << cX << ";\n" << "\t\treal_t b = vIn.y - " << cY << ";\n" << "\t\treal_t c = 1 - " << cX << " * vIn.x - " << cY << " * vIn.y;\n" << "\t\treal_t d = fma(" << cY << ", vIn.x, -(" << cX << " * vIn.y));\n" << "\t\treal_t num = " << weight << " / Zeps(fma(c, c, d * d));\n" << "\n" << "\t\tvOut.x = fma(a, c, b * d) * num;\n" << "\t\tvOut.y = fma(b, c, -(a * d)) * num;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } virtual void Precalc() override { T a0 = M_2PI / m_PoincareP; T dist2 = 1 - (std::cos(a0) - 1) / (std::cos(a0) + std::cos(M_2PI / m_PoincareQ)); T dist = (dist2 > 0) ? T(1) / std::sqrt(dist2) : T(1); if (1 / m_PoincareP + 1 / m_PoincareQ < T(0.5)) { m_Cx = std::cos(a0) * dist; m_Cy = std::sin(a0) * dist; } else m_Cx = m_Cy = 0; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_PoincareP, prefix + "poincare2_p", 3)); m_Params.push_back(ParamWithName(&m_PoincareQ, prefix + "poincare2_q", 7)); m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "poincare2_cx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cy, prefix + "poincare2_cy")); } private: T m_PoincareP; T m_PoincareQ; T m_Cx;//Precalc. T m_Cy; }; /// /// Poincare3D. /// template class Poincare3DVariation : public ParametricVariation { public: Poincare3DVariation(T weight = 1.0) : ParametricVariation("poincare3D", eVariationId::VAR_POINCARE3D, weight, true) { Init(); } PARVARCOPY(Poincare3DVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r2 = helper.m_PrecalcSumSquares + SQR(helper.In.z); T x2cx = m_C2x * helper.In.x; T y2cy = m_C2y * helper.In.y; T z2cz = m_C2z * helper.In.z; T val = Zeps(m_C2 * r2 - x2cx - y2cy - z2cz + 1); T d = m_Weight / val; helper.Out.x = d * (helper.In.x * m_S2x + m_Cx * (y2cy + z2cz - r2 - 1)); helper.Out.y = d * (helper.In.y * m_S2y + m_Cy * (x2cx + z2cz - r2 - 1)); helper.Out.z = d * (helper.In.z * m_S2z + m_Cz * (y2cy + x2cx - r2 - 1)); } virtual string OpenCLString() const override { ostringstream ss, ss2; intmax_t i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string b = "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 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; string s2x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s2z = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r2 = fma(vIn.z, vIn.z, precalcSumSquares);\n" << "\t\treal_t x2cx = " << c2x << " * vIn.x;\n" << "\t\treal_t y2cy = " << c2y << " * vIn.y;\n" << "\t\treal_t z2cz = " << c2z << " * vIn.z;\n" << "\t\treal_t val = Zeps(" << c2 << " * r2 - x2cx - y2cy - z2cz + (real_t)(1.0));\n" << "\t\treal_t d = " << weight << " / val;\n" << "\n" << "\t\tvOut.x = d * fma(vIn.x, " << s2x << ", " << cx << " * (y2cy + z2cz - r2 - (real_t)(1.0)));\n" << "\t\tvOut.y = d * fma(vIn.y, " << s2y << ", " << cy << " * (x2cx + z2cz - r2 - (real_t)(1.0)));\n" << "\t\tvOut.z = d * fma(vIn.z, " << s2z << ", " << cz << " * (y2cy + x2cx - r2 - (real_t)(1.0)));\n" << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } virtual void Precalc() override { m_Cx = -m_R * std::cos(m_A * T(M_PI_2)) * std::cos(m_B * T(M_PI_2)); m_Cy = m_R * std::sin(m_A * T(M_PI_2)) * std::cos(m_B * T(M_PI_2)); m_Cz = -m_R * std::sin(m_B * T(M_PI_2)); m_C2 = SQR(m_Cx) + SQR(m_Cy) + SQR(m_Cz); m_C2x = 2 * m_Cx; m_C2y = 2 * m_Cy; m_C2z = 2 * m_Cz; m_S2x = SQR(m_Cx) - SQR(m_Cy) - SQR(m_Cz) + 1; m_S2y = SQR(m_Cy) - SQR(m_Cx) - SQR(m_Cz) + 1; m_S2z = SQR(m_Cz) - SQR(m_Cy) - SQR(m_Cx) + 1; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_R, prefix + "poincare3D_r")); m_Params.push_back(ParamWithName(&m_A, prefix + "poincare3D_a")); m_Params.push_back(ParamWithName(&m_B, prefix + "poincare3D_b")); m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "poincare3D_cx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cy, prefix + "poincare3D_cy")); m_Params.push_back(ParamWithName(true, &m_Cz, prefix + "poincare3D_cz")); m_Params.push_back(ParamWithName(true, &m_C2, prefix + "poincare3D_c2")); m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "poincare3D_c2x")); m_Params.push_back(ParamWithName(true, &m_C2y, prefix + "poincare3D_c2y")); m_Params.push_back(ParamWithName(true, &m_C2z, prefix + "poincare3D_c2z")); m_Params.push_back(ParamWithName(true, &m_S2x, prefix + "poincare3D_s2x")); m_Params.push_back(ParamWithName(true, &m_S2y, prefix + "poincare3D_s2y")); m_Params.push_back(ParamWithName(true, &m_S2z, prefix + "poincare3D_s2z")); } private: T m_R; T m_A; T m_B; T m_Cx;//Precalc. T m_Cy; T m_Cz; T m_C2; T m_C2x; T m_C2y; T m_C2z; T m_S2x; T m_S2y; T m_S2z; }; /// /// Polynomial. /// template class PolynomialVariation : public ParametricVariation { public: PolynomialVariation(T weight = 1.0) : ParametricVariation("polynomial", eVariationId::VAR_POLYNOMIAL, weight) { Init(); } PARVARCOPY(PolynomialVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T xp = std::pow(std::abs(m_Weight) * std::abs(helper.In.x), m_Powx);//Original did not fabs. T yp = std::pow(std::abs(m_Weight) * std::abs(helper.In.y), m_Powy); helper.Out.x = xp * VarFuncs::Sign(helper.In.x) + m_Lcx * helper.In.x + m_Scx; helper.Out.y = yp * VarFuncs::Sign(helper.In.y) + m_Lcy * helper.In.y + m_Scy; 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 powx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string powy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string lcx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string lcy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t xp = pow(fabs(" << weight << ") * fabs(vIn.x), " << powx << ");\n" << "\t\treal_t yp = pow(fabs(" << weight << ") * fabs(vIn.y), " << powy << ");\n" << "\t\treal_t zp = " << weight << " * vIn.z;\n" << "\n" << "\t\tvOut.x = fma(xp, Sign(vIn.x), fma(" << lcx << ", vIn.x, " << scx << "));\n" << "\t\tvOut.y = fma(yp, Sign(vIn.y), fma(" << lcy << ", vIn.y, " << scy << "));\n" << "\t\tvOut.z = zp;\n" << "\t}\n"; return ss.str(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Powx, prefix + "polynomial_powx", 1)); m_Params.push_back(ParamWithName(&m_Powy, prefix + "polynomial_powy", 1)); m_Params.push_back(ParamWithName(&m_Lcx, prefix + "polynomial_lcx")); m_Params.push_back(ParamWithName(&m_Lcy, prefix + "polynomial_lcy")); m_Params.push_back(ParamWithName(&m_Scx, prefix + "polynomial_scx")); m_Params.push_back(ParamWithName(&m_Scy, prefix + "polynomial_scy")); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Sign" }; } private: T m_Powx; T m_Powy; T m_Lcx; T m_Lcy; T m_Scx; T m_Scy; }; /// /// PSphere. /// template class PSphereVariation : public ParametricVariation { public: PSphereVariation(T weight = 1.0) : ParametricVariation("psphere", eVariationId::VAR_PSPHERE, weight) { Init(); } PARVARCOPY(PSphereVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T c0 = helper.In.x * m_Vpi; T c1 = helper.In.y * m_Vpi; T sinc0, cosc0, sinc1, cosc1; sincos(c0, &sinc0, &cosc0); sincos(c1, &sinc1, &cosc1); helper.Out.x = cosc0 * -sinc1; helper.Out.y = sinc0 * cosc1; helper.Out.z = cosc1 * m_ZScale; } virtual string OpenCLString() const override { ostringstream ss, ss2; int i = 0; ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weight = WeightDefineString(); string zscale = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vpi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t c0 = vIn.x * " << vpi << ";\n" << "\t\treal_t c1 = vIn.y * " << vpi << ";\n" << "\n" << "\t\treal_t sinc0 = sin(c0);\n" << "\t\treal_t cosc0 = cos(c0);\n" << "\t\treal_t sinc1 = sin(c1);\n" << "\t\treal_t cosc1 = cos(c1);\n" << "\n" << "\t\tvOut.x = cosc0 * -sinc1;\n" << "\t\tvOut.y = sinc0 * cosc1;\n" << "\t\tvOut.z = cosc1 * " << zscale << ";\n" << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Vpi = m_Weight * T(M_PI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_ZScale, prefix + "psphere_zscale")); m_Params.push_back(ParamWithName(true, &m_Vpi, prefix + "psphere_vpi"));//Precalc. } private: T m_ZScale; T m_Vpi;//Precalc. }; /// /// Rational3. /// template class Rational3Variation : public ParametricVariation { public: Rational3Variation(T weight = 1.0) : ParametricVariation("rational3", eVariationId::VAR_RATIONAL3, weight) { Init(); } PARVARCOPY(Rational3Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T xsqr = helper.In.x * helper.In.x; T ysqr = helper.In.y * helper.In.y; T xcb = helper.In.x * helper.In.x * helper.In.x; T ycb = helper.In.y * helper.In.y * helper.In.y; T tr = m_T3 * (xcb - 3 * helper.In.x * ysqr) + m_T2 * (xsqr - ysqr) + m_T1 * helper.In.x + m_Tc; T ti = m_T3 * (3 * xsqr * helper.In.y - ycb) + m_T2 * 2 * helper.In.x * helper.In.y + m_T1 * helper.In.y; T br = m_B3 * (xcb - 3 * helper.In.x * ysqr) + m_B2 * (xsqr - ysqr) + m_B1 * helper.In.x + m_Bc; T bi = m_B3 * (3 * xsqr * helper.In.y - ycb) + m_B2 * 2 * helper.In.x * helper.In.y + m_B1 * helper.In.y; T r3den = 1 / Zeps(br * br + bi * bi); helper.Out.x = m_Weight * (tr * br + ti * bi) * r3den; helper.Out.y = m_Weight * (ti * br - tr * bi) * r3den; 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 t3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string t2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string t1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string tc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string b3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string b2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string b1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string bc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t xsqr = vIn.x * vIn.x;\n" << "\t\treal_t ysqr = vIn.y * vIn.y;\n" << "\t\treal_t xcb = vIn.x * vIn.x * vIn.x;\n" << "\t\treal_t ycb = vIn.y * vIn.y * vIn.y;\n" << "\n" << "\t\treal_t tr = fma(" << t3 << ", (xcb - (real_t)(3.0) * vIn.x * ysqr), fma(" << t2 << ", (xsqr - ysqr), fma(" << t1 << ", vIn.x, " << tc << ")));\n" << "\t\treal_t ti = fma(" << t3 << ", ((real_t)(3.0) * xsqr * vIn.y - ycb), fma(" << t2 << " * (real_t)(2.0), vIn.x * vIn.y, " << t1 << " * vIn.y));\n" << "\n" << "\t\treal_t br = fma(" << b3 << ", (xcb - (real_t)(3.0) * vIn.x * ysqr), fma(" << b2 << ", (xsqr - ysqr), fma(" << b1 << ", vIn.x, " << bc << ")));\n" << "\t\treal_t bi = fma(" << b3 << ", ((real_t)(3.0) * xsqr * vIn.y - ycb), fma(" << b2 << ", (real_t)(2.0) * vIn.x * vIn.y, " << b1 << " * vIn.y));\n" << "\n" << "\t\treal_t r3den = 1 / Zeps(fma(br, br, bi * bi));\n" << "\n" << "\t\tvOut.x = " << weight << " * fma(tr, br, ti * bi) * r3den;\n" << "\t\tvOut.y = " << weight << " * fma(ti, br, -(tr * bi)) * r3den;\n" << "\t\tvOut.z = " << DefaultZCl() << "\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_T3, prefix + "rational3_t3", 1)); m_Params.push_back(ParamWithName(&m_T2, prefix + "rational3_t2")); m_Params.push_back(ParamWithName(&m_T1, prefix + "rational3_t1")); m_Params.push_back(ParamWithName(&m_Tc, prefix + "rational3_tc", 1)); m_Params.push_back(ParamWithName(&m_B3, prefix + "rational3_b3")); m_Params.push_back(ParamWithName(&m_B2, prefix + "rational3_b2", 1)); m_Params.push_back(ParamWithName(&m_B1, prefix + "rational3_b1")); m_Params.push_back(ParamWithName(&m_Bc, prefix + "rational3_bc", 1)); } private: T m_T3; T m_T2; T m_T1; T m_Tc; T m_B3; T m_B2; T m_B1; T m_Bc; }; /// /// Ripple. /// template class RippleVariation : public ParametricVariation { public: RippleVariation(T weight = 1.0) : ParametricVariation("ripple", eVariationId::VAR_RIPPLE, weight) { Init(); } PARVARCOPY(RippleVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { //Align input x, y to given center and multiply with scale. T x = (helper.In.x * m_S) - m_CenterX; T y = (helper.In.y * m_S) + m_CenterY; //Calculate distance from center but constrain it to EPS. T d = std::max(EPS, std::sqrt(SQR(x) * SQR(y))); //Normalize x and y. T nx = x / d; T ny = y / d; //Calculate cosine wave with given frequency, velocity //and phase based on the distance to center. T wave = std::cos(m_F * d - m_Vxp); //Calculate the wave offsets T d1 = wave * m_Pxa + d; T d2 = wave * m_Pixa + d; //We got two offsets, so we also got two new positions (u,v). T u1 = m_CenterX + nx * d1; T v1 = -m_CenterY + ny * d1; T u2 = m_CenterX + nx * d2; T v2 = -m_CenterY + ny * d2; //Interpolate the two positions by the given phase and //invert the multiplication with scale from before. helper.Out.x = m_Weight * Lerp(u1, u2, m_P) * m_Is;//Original did a direct assignment to outPoint, which is incompatible with Ember's design. helper.Out.y = m_Weight * Lerp(v1, v2, m_P) * m_Is; 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 frequency = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string velocity = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string amplitude = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string centerx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string centery = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string phase = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string f = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string p = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string is = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vxp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pxa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pixa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = fma(vIn.x, " << s << ", -" << centerx << ");\n" << "\t\treal_t y = fma(vIn.y, " << s << ", " << centery << ");\n" << "\n" << "\t\treal_t d = max(EPS, sqrt(SQR(x) * SQR(y)));\n" << "\n" << "\t\treal_t nx = x / d;\n" << "\t\treal_t ny = y / d;\n" << "\n" << "\t\treal_t wave = cos(fma(" << f << ", d, -" << vxp << "));\n" << "\n" << "\t\treal_t d1 = fma(wave, " << pxa << ", d);\n" << "\t\treal_t d2 = fma(wave, " << pixa << ", d);\n" << "\n" << "\t\treal_t u1 = fma(nx, d1, " << centerx << ");\n" << "\t\treal_t v1 = fma(ny, d1, -" << centery << ");\n" << "\t\treal_t u2 = fma(nx, d2, " << centerx << ");\n" << "\t\treal_t v2 = fma(ny, d2, -" << centery << ");\n" << "\n" << "\t\tvOut.x = " << weight << " * Lerp(u1, u2, " << p << ") * " << is << ";\n" << "\t\tvOut.y = " << weight << " * Lerp(v1, v2, " << p << ") * " << is << ";\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Lerp" }; } virtual void Precalc() override { m_F = m_Frequency * 5; m_A = m_Amplitude * T(0.01); m_P = m_Phase * M_2PI - T(M_PI); m_S = Zeps(m_Scale);//Scale must not be zero. m_Is = 1 / m_S;//Need the inverse scale. //Pre-multiply velocity + phase, phase + amplitude and (PI - phase) + amplitude. m_Vxp = m_Velocity * m_P; m_Pxa = m_P * m_A; m_Pixa = (T(M_PI) - m_P) * m_A; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Frequency, prefix + "ripple_frequency", 2)); m_Params.push_back(ParamWithName(&m_Velocity, prefix + "ripple_velocity", 1)); m_Params.push_back(ParamWithName(&m_Amplitude, prefix + "ripple_amplitude", T(0.5))); m_Params.push_back(ParamWithName(&m_CenterX, prefix + "ripple_centerx")); m_Params.push_back(ParamWithName(&m_CenterY, prefix + "ripple_centery")); m_Params.push_back(ParamWithName(&m_Phase, prefix + "ripple_phase")); m_Params.push_back(ParamWithName(&m_Scale, prefix + "ripple_scale", 1)); m_Params.push_back(ParamWithName(true, &m_F, prefix + "ripple_f"));//Precalc. m_Params.push_back(ParamWithName(true, &m_A, prefix + "ripple_a")); m_Params.push_back(ParamWithName(true, &m_P, prefix + "ripple_p")); m_Params.push_back(ParamWithName(true, &m_S, prefix + "ripple_s")); m_Params.push_back(ParamWithName(true, &m_Is, prefix + "ripple_is")); m_Params.push_back(ParamWithName(true, &m_Vxp, prefix + "ripple_vxp")); m_Params.push_back(ParamWithName(true, &m_Pxa, prefix + "ripple_pxa")); m_Params.push_back(ParamWithName(true, &m_Pixa, prefix + "ripple_pixa")); } private: T m_Frequency; T m_Velocity; T m_Amplitude; T m_CenterX; T m_CenterY; T m_Phase; T m_Scale; T m_F;//Precalc. T m_A; T m_P; T m_S; T m_Is; T m_Vxp; T m_Pxa; T m_Pixa; }; /// /// Sigmoid. /// template class SigmoidVariation : public ParametricVariation { public: SigmoidVariation(T weight = 1.0) : ParametricVariation("sigmoid", eVariationId::VAR_SIGMOID, weight) { Init(); } PARVARCOPY(SigmoidVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T c0 = m_Ax / Zeps(1 + std::exp(m_Sx * helper.In.x)); T c1 = m_Ay / Zeps(1 + std::exp(m_Sy * helper.In.y)); T x = (2 * (c0 - T(0.5))); T y = (2 * (c1 - T(0.5))); helper.Out.x = m_Vv * x; helper.Out.y = m_Vv * y; 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 shiftX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string shiftY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ax = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ay = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vv = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t c0 = " << ax << " / Zeps(1 + exp(" << sx << " * vIn.x));\n" << "\t\treal_t c1 = " << ay << " / Zeps(1 + exp(" << sy << " * vIn.y));\n" << "\t\treal_t x = (2 * (c0 - (real_t)(0.5)));\n" << "\t\treal_t y = (2 * (c1 - (real_t)(0.5)));\n" << "\n" << "\t\tvOut.x = " << vv << " * x;\n" << "\t\tvOut.y = " << vv << " * y;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Sx = m_ShiftX; m_Sy = m_ShiftY; m_Ax = 1; m_Ay = 1; if (m_Sx < 1 && m_Sx > -1) { if (m_Sx == 0) { m_Sx = EPS; m_Ax = 1; } else { m_Ax = T(m_Sx < 0 ? -1 : 1); m_Sx = 1 / m_Sx; } } if (m_Sy < 1 && m_Sy > -1) { if (m_Sy == 0) { m_Sy = EPS; m_Ay = 1; } else { m_Ay = T(m_Sy < 0 ? -1 : 1); m_Sy = 1 / m_Sy; } } m_Sx *= -5; m_Sy *= -5; m_Vv = std::abs(m_Weight); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_ShiftX, prefix + "sigmoid_shiftx", 1)); m_Params.push_back(ParamWithName(&m_ShiftY, prefix + "sigmoid_shifty", 1)); m_Params.push_back(ParamWithName(true, &m_Sx, prefix + "sigmoid_sx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Sy, prefix + "sigmoid_sy")); m_Params.push_back(ParamWithName(true, &m_Ax, prefix + "sigmoid_ax")); m_Params.push_back(ParamWithName(true, &m_Ay, prefix + "sigmoid_ay")); m_Params.push_back(ParamWithName(true, &m_Vv, prefix + "sigmoid_vv")); } private: T m_ShiftX; T m_ShiftY; T m_Sx;//Precalc. T m_Sy; T m_Ax; T m_Ay; T m_Vv; }; /// /// SinusGrid. /// template class SinusGridVariation : public ParametricVariation { public: SinusGridVariation(T weight = 1.0) : ParametricVariation("sinusgrid", eVariationId::VAR_SINUS_GRID, weight) { Init(); } PARVARCOPY(SinusGridVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T x = helper.In.x; T y = helper.In.y; T sx = -1 * std::cos(x * m_Fx); T sy = -1 * std::cos(y * m_Fy); T tx = Lerp(helper.In.x, sx, m_Ax); T ty = Lerp(helper.In.y, sy, m_Ay); helper.Out.x = m_Weight * tx; helper.Out.y = m_Weight * ty; 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 ampX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ampY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string freqX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string freqY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string fx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string fy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ax = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ay = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = vIn.x;\n" << "\t\treal_t y = vIn.y;\n" << "\t\treal_t sx = -1 * cos(x * " << fx << ");\n" << "\t\treal_t sy = -1 * cos(y * " << fy << ");\n" << "\t\treal_t tx = Lerp(vIn.x, sx, " << ax << ");\n" << "\t\treal_t ty = Lerp(vIn.y, sy, " << ay << ");\n" << "\t\treal_t tz = vIn.z;\n" << "\n" << "\t\tvOut.x = " << weight << " * tx;\n" << "\t\tvOut.y = " << weight << " * ty;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Lerp" }; } virtual void Precalc() override { m_Ax = m_AmpX; m_Ay = m_AmpY; m_Fx = Zeps(m_FreqX * M_2PI); m_Fy = Zeps(m_FreqY * M_2PI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_AmpX, prefix + "sinusgrid_ampx", T(0.5))); m_Params.push_back(ParamWithName(&m_AmpY, prefix + "sinusgrid_ampy", T(0.5))); m_Params.push_back(ParamWithName(&m_FreqX, prefix + "sinusgrid_freqx", 1)); m_Params.push_back(ParamWithName(&m_FreqY, prefix + "sinusgrid_freqy", 1)); m_Params.push_back(ParamWithName(true, &m_Fx, prefix + "sinusgrid_fx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Fy, prefix + "sinusgrid_fy")); m_Params.push_back(ParamWithName(true, &m_Ax, prefix + "sinusgrid_ax")); m_Params.push_back(ParamWithName(true, &m_Ay, prefix + "sinusgrid_ay")); } private: T m_AmpX; T m_AmpY; T m_FreqX; T m_FreqY; T m_Fx;//Precalc. T m_Fy; T m_Ax; T m_Ay; }; /// /// Stwin. /// template class StwinVariation : public ParametricVariation { public: StwinVariation(T weight = 1.0) : ParametricVariation("stwin", eVariationId::VAR_STWIN, weight) { Init(); } PARVARCOPY(StwinVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { const T multiplier = T(0.05); T x = helper.In.x * m_Weight * multiplier; T y = helper.In.y * m_Weight * multiplier; T x2 = SQR(x); T y2 = SQR(y); T xPlusy = x + y; T x2Minusy2 = x2 - y2; T x2Plusy2 = x2 + y2; T result = x2Minusy2 * std::sin(M_2PI * m_Distort * xPlusy); T divident = 1; if (x2Plusy2 != 0) divident = x2Plusy2; result /= divident; helper.Out.x = m_Weight * helper.In.x + result; helper.Out.y = m_Weight * helper.In.y + result; 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 distort = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = vIn.x * " << weight << " * (real_t)(0.05);\n" << "\t\treal_t y = vIn.y * " << weight << " * (real_t)(0.05);\n" << "\t\treal_t x2 = SQR(x);\n" << "\t\treal_t y2 = SQR(y);\n" << "\t\treal_t xPlusy = x + y;\n" << "\t\treal_t x2Minusy2 = x2 - y2;\n" << "\t\treal_t x2Plusy2 = x2 + y2;\n" << "\t\treal_t result = x2Minusy2 * sin(M_2PI * " << distort << " * xPlusy);\n" << "\t\treal_t divident = 1;\n" << "\n" << "\t\tif (x2Plusy2 != 0)\n" << "\t\t divident = x2Plusy2;\n" << "\n" << "\t\tresult /= divident;\n" << "\n" << "\t\tvOut.x = fma(" << weight << ", vIn.x, result);\n" << "\t\tvOut.y = fma(" << weight << ", vIn.y, result);\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_Distort, prefix + "stwin_distort", 1));//Original had a misspelling of swtin, which is incompatible with Ember's design. } private: T m_Distort; }; /// /// TwoFace. /// template class TwoFaceVariation : public Variation { public: TwoFaceVariation(T weight = 1.0) : Variation("twoface", eVariationId::VAR_TWO_FACE, weight, true) { } VARCOPY(TwoFaceVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r = m_Weight; if (helper.In.x > 0) r /= helper.m_PrecalcSumSquares; helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t r = " << weight << ";\n" << "\n" << "\t\tif (vIn.x > 0)\n" << "\t\t r /= precalcSumSquares;\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } }; /// /// Unpolar. /// template class UnpolarVariation : public ParametricVariation { public: UnpolarVariation(T weight = 1.0) : ParametricVariation("unpolar", eVariationId::VAR_UNPOLAR, weight) { Init(); } PARVARCOPY(UnpolarVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r = std::exp(helper.In.y); T s = std::sin(helper.In.x); T c = std::cos(helper.In.x); helper.Out.x = m_Vvar2 * r * s; helper.Out.y = m_Vvar2 * r * c; 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 vvar2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. ss << "\t{\n" << "\t\treal_t r = exp(vIn.y);\n" << "\t\treal_t s = sin(vIn.x);\n" << "\t\treal_t c = cos(vIn.x);\n" << "\n" << "\t\tvOut.x = " << vvar2 << " * r * s;\n" << "\t\tvOut.y = " << vvar2 << " * r * c;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Vvar2 = (m_Weight / T(M_PI)) * T(0.5); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_Vvar2, prefix + "unpolar_vvar_2"));//Precalcs only, no params. } private: T m_Vvar2;//Precalcs only, no params. }; /// /// WavesN. /// template class WavesNVariation : public ParametricVariation { public: WavesNVariation(T weight = 1.0) : ParametricVariation("wavesn", eVariationId::VAR_WAVESN, weight, true, false, false, false, true) { Init(); } PARVARCOPY(WavesNVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T angle = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(int(m_AbsN))) / m_Power; T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); T sina = std::sin(angle); T cosa = std::cos(angle); T xn = r * cosa; T yn = r * sina; T siny = std::sin(m_FreqX * yn); T sinx = std::sin(m_FreqY * xn); T dx = xn + T(0.5) * (m_ScaleX * siny + std::abs(xn) * m_IncX * siny); T dy = yn + T(0.5) * (m_ScaleY * sinx + std::abs(yn) * m_IncY * sinx); helper.Out.x = m_Weight * dx; helper.Out.y = m_Weight * dy; 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 freqX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string freqY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scaleX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scaleY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string incX = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string incY = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string absn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t angle = fma(M_2PI, (real_t)MwcNextRange(mwc, (uint)" << absn << "), precalcAtanyx) / " << power << ";\n" << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" << "\t\treal_t sina = sin(angle);\n" << "\t\treal_t cosa = cos(angle);\n" << "\t\treal_t xn = r * cosa;\n" << "\t\treal_t yn = r * sina;\n" << "\t\treal_t siny = sin(" << freqX << " * yn);\n" << "\t\treal_t sinx = sin(" << freqY << " * xn);\n" << "\t\treal_t dx = fma((real_t)(0.5), fma(" << scaleX << ", siny, fabs(xn) * " << incX << " * siny), xn);\n" << "\t\treal_t dy = fma((real_t)(0.5), fma(" << scaleY << ", sinx, fabs(yn) * " << incY << " * sinx), yn);\n" << "\n" << "\t\tvOut.x = " << weight << " * dx;\n" << "\t\tvOut.y = " << weight << " * dy;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { if (m_Power == 0) m_Power = 2; m_AbsN = T(int(std::abs(m_Power))); m_Cn = 1 / m_Power / 2; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_FreqX, prefix + "wavesn_freqx", 2)); m_Params.push_back(ParamWithName(&m_FreqY, prefix + "wavesn_freqy", 2)); m_Params.push_back(ParamWithName(&m_ScaleX, prefix + "wavesn_scalex", 1)); m_Params.push_back(ParamWithName(&m_ScaleY, prefix + "wavesn_scaley", 1)); m_Params.push_back(ParamWithName(&m_IncX, prefix + "wavesn_incx")); m_Params.push_back(ParamWithName(&m_IncY, prefix + "wavesn_incy")); m_Params.push_back(ParamWithName(&m_Power, prefix + "wavesn_power", 1, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "wavesn_absn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "wavesn_cn")); } private: T m_FreqX; T m_FreqY; T m_ScaleX; T m_ScaleY; T m_IncX; T m_IncY; T m_Power; T m_AbsN;//Precalc. T m_Cn; }; /// /// XHeart. /// template class XHeartVariation : public ParametricVariation { public: XHeartVariation(T weight = 1.0) : ParametricVariation("xheart", eVariationId::VAR_XHEART, weight, true) { Init(); } PARVARCOPY(XHeartVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T r2_4 = helper.m_PrecalcSumSquares + 4; if (r2_4 == 0) r2_4 = 1; T bx = 4 / r2_4; T by = m_Rat / r2_4; T x = m_Cosa * (bx * helper.In.x) - m_Sina * (by * helper.In.y); T y = m_Sina * (bx * helper.In.x) + m_Cosa * (by * helper.In.y); if (x > 0) { helper.Out.x = m_Weight * x; helper.Out.y = m_Weight * y; } else { helper.Out.x = m_Weight * x; helper.Out.y = -m_Weight * y; } 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 angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ratio = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cosa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sina = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rat = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r2_4 = precalcSumSquares + 4;\n" << "\n" << "\t\tif (r2_4 == 0)\n" << "\t\t r2_4 = 1;\n" << "\n" << "\t\treal_t bx = 4 / r2_4;\n" << "\t\treal_t by = " << rat << " / r2_4;\n" << "\t\treal_t bxx = bx * vIn.x;\n" << "\t\treal_t byy = by * vIn.y;\n" << "\t\treal_t x = fma(" << cosa << ", bxx, -(" << sina << " * byy));\n" << "\t\treal_t y = fma(" << sina << ", bxx, " << cosa << " * byy);\n" << "\n" << "\t\tif (x > 0)\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 vOut.x = " << weight << " * x;\n" << "\t\t vOut.y = -" << weight << " * y;\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { T ang = T(M_PI_4) + (T(0.5) * T(M_PI_4) * m_Angle); sincos(ang, &m_Sina, &m_Cosa); m_Rat = 6 + 2 * m_Ratio; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "xheart_angle")); m_Params.push_back(ParamWithName(&m_Ratio, prefix + "xheart_ratio")); m_Params.push_back(ParamWithName(true, &m_Cosa, prefix + "xheart_cosa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Sina, prefix + "xheart_sina")); m_Params.push_back(ParamWithName(true, &m_Rat, prefix + "xheart_rat")); } private: T m_Angle; T m_Ratio; T m_Cosa;//Precalc. T m_Sina; T m_Rat; }; /// /// Barycentroid. /// template class BarycentroidVariation : public ParametricVariation { public: BarycentroidVariation(T weight = 1.0) : ParametricVariation("barycentroid", eVariationId::VAR_BARYCENTROID, weight) { Init(); } PARVARCOPY(BarycentroidVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { //Compute dot products. T dot00 = SQR(m_A) + SQR(m_B);//v0 * v0. T dot01 = m_A * m_C + m_B * m_D;//v0 * v1. T dot02 = m_A * helper.In.x + m_B * helper.In.y;//v0 * v2. T dot11 = SQR(m_C) + SQR(m_D);//v1 * v1. T dot12 = m_C * helper.In.x + m_D * helper.In.y;//v1 * v2. //Compute inverse denomiator. T invDenom = 1 / Zeps(dot00 * dot11 - dot01 * dot01); //Now we can pull [u,v] as the barycentric coordinates of the point //P in the triangle [A, B, C]. T u = (dot11 * dot02 - dot01 * dot12) * invDenom; T v = (dot00 * dot12 - dot01 * dot02) * invDenom; // now combine with input T um = std::sqrt(SQR(u) + SQR(helper.In.x)) * VarFuncs::Sign(u); T vm = std::sqrt(SQR(v) + SQR(helper.In.y)) * VarFuncs::Sign(v); helper.Out.x = m_Weight * um; helper.Out.y = m_Weight * vm; 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 a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string b = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t dot00 = fma(" << a << ", " << a << ", SQR(" << b << "));\n" << "\t\treal_t dot01 = fma(" << a << ", " << c << ", " << b << " * " << d << ");\n" << "\t\treal_t dot02 = fma(" << a << ", vIn.x, " << b << " * vIn.y);\n" << "\t\treal_t dot11 = fma(" << c << ", " << c << ", SQR(" << d << "));\n" << "\t\treal_t dot12 = fma(" << c << ", vIn.x, " << d << " * vIn.y);\n" << "\t\treal_t invDenom = (real_t)(1.0) / Zeps(fma(dot00, dot11, -(dot01 * dot01)));\n" << "\t\treal_t u = fma(dot11, dot02, -(dot01 * dot12)) * invDenom;\n" << "\t\treal_t v = fma(dot00, dot12, -(dot01 * dot02)) * invDenom;\n" << "\t\treal_t um = sqrt(fma(u, u, SQR(vIn.x))) * Sign(u);\n" << "\t\treal_t vm = sqrt(fma(v, v, SQR(vIn.y))) * Sign(v);\n" << "\n" << "\t\tvOut.x = " << weight << " * um;\n" << "\t\tvOut.y = " << weight << " * vm;\n" << "\t\tvOut.z = " << weight << " * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Sign", "Zeps" }; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_A, prefix + "barycentroid_a", 1)); m_Params.push_back(ParamWithName(&m_B, prefix + "barycentroid_b")); m_Params.push_back(ParamWithName(&m_C, prefix + "barycentroid_c")); m_Params.push_back(ParamWithName(&m_D, prefix + "barycentroid_d", 1)); } private: T m_A; T m_B; T m_C; T m_D; }; /// /// BiSplit. /// template class BiSplitVariation : public ParametricVariation { public: BiSplitVariation(T weight = 1.0) : ParametricVariation("bisplit", eVariationId::VAR_BISPLIT, weight) { Init(); } PARVARCOPY(BiSplitVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { helper.Out.x = m_Weight01 / SafeTan(helper.In.x) * std::cos(helper.In.y); helper.Out.y = m_Weight01 / std::sin(helper.In.x) * (-helper.In.y); 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 weight01 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = " << weight01 << " / tan(vIn.x) * cos(vIn.y);\n" << "\t\tvOut.y = " << weight01 << " / sin(vIn.x) * (-vIn.y);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Weight01 = m_Weight * T(0.1); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_Weight01, prefix + "bisplit_weight01"));//Precalc only. } private: T m_Weight01; }; /// /// Crescents. /// template class CrescentsVariation : public Variation { public: CrescentsVariation(T weight = 1.0) : Variation("crescents", eVariationId::VAR_CRESCENTS, weight) { } VARCOPY(CrescentsVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T sinx = std::sin(helper.In.x); T sinx2 = SQR(sinx); T cosx = std::cos(helper.In.x); T coshy1 = std::cosh(helper.In.y) + 1; helper.Out.x = m_Weight * sinx * coshy1 * sinx2; helper.Out.y = m_Weight * cosx * coshy1 * sinx2; helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t sinx = sin(vIn.x);\n" << "\t\treal_t sinx2 = SQR(sinx);\n" << "\t\treal_t cosx = cos(vIn.x);\n" << "\t\treal_t coshy1 = cosh(vIn.y) + 1.0;\n" << "\n" << "\t\tvOut.x = " << weight << " * sinx * coshy1 * sinx2;\n" << "\t\tvOut.y = " << weight << " * cosx * coshy1 * sinx2;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } }; /// /// Mask. /// template class MaskVariation : public Variation { public: MaskVariation(T weight = 1.0) : Variation("mask", eVariationId::VAR_MASK, weight, true) { } VARCOPY(MaskVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T d = m_Weight / Zeps(helper.m_PrecalcSumSquares); T sinx = std::sin(helper.In.x); T sinx2 = SQR(sinx); T cosx = std::cos(helper.In.x); T coshy1 = std::cosh(helper.In.y) + 1; helper.Out.x = d * sinx * coshy1 * sinx2; helper.Out.y = d * cosx * coshy1 * sinx2; helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override { ostringstream ss; intmax_t varIndex = IndexInXform(); string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t d = " << weight << " / Zeps(precalcSumSquares);\n" << "\t\treal_t sinx = sin(vIn.x);\n" << "\t\treal_t sinx2 = SQR(sinx);\n" << "\t\treal_t cosx = cos(vIn.x);\n" << "\t\treal_t coshy1 = cosh(vIn.y) + 1.0;\n" << "\n" << "\t\tvOut.x = d * sinx * coshy1 * sinx2;\n" << "\t\tvOut.y = d * cosx * coshy1 * sinx2;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual vector OpenCLGlobalFuncNames() const override { return vector { "Zeps" }; } }; /// /// Cpow2. /// template class Cpow2Variation : public ParametricVariation { public: Cpow2Variation(T weight = 1.0) : ParametricVariation("cpow2", eVariationId::VAR_CPOW2, weight, true, false, false, false, true) { Init(); } PARVARCOPY(Cpow2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T a = helper.m_PrecalcAtanyx; int n = rand.Rand(m_SpreadUint); if (a < 0) n++; a += M_2PI * n; if (std::cos(a * m_InvSpread) < rand.Rand() * T(2) / 0xFFFFFFFF - T(1))//Rand max. a -= m_FullSpread; T lnr2 = std::log(helper.m_PrecalcSumSquares); T r = m_Weight * std::exp(m_HalfC * lnr2 - m_D * a); T temp = m_C * a + m_HalfD * lnr2 + m_Ang * rand.Rand(); helper.Out.x = r * std::cos(temp); helper.Out.y = r * std::sin(temp); 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 r = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string divisor = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string spread = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string halfC = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string halfD = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ang = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string invSpread = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string fullSpread = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = precalcAtanyx;\n" << "\t\tint n = MwcNextRange(mwc, (uint)" << spread << ");\n" << "\n" << "\t\tif (a < 0)\n" << "\t\t n++;\n" << "\n" << "\t\ta += M_2PI * n;\n" << "\n" << "\t\tif (cos(a * " << invSpread << ") < MwcNext(mwc) * (real_t)2.0 / 0xFFFFFFFF - (real_t)1.0)\n" << "\t\t a -= " << fullSpread << ";\n" << "\n" << "\t\treal_t lnr2 = log(precalcSumSquares);\n" << "\t\treal_t r = " << weight << " * exp(fma(" << halfC << ", lnr2, -(" << d << " * a)));\n" << "\t\treal_t temp = fma(" << c << ", a, fma(" << halfD << ", lnr2, " << ang << " * MwcNext(mwc)));\n" << "\n" << "\t\tvOut.x = r * cos(temp);\n" << "\t\tvOut.y = r * sin(temp);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { m_Ang = M_2PI / m_Divisor; m_C = m_R * std::cos(T(M_PI) / 2 * m_A) / m_Divisor; m_D = m_R * std::sin(T(M_PI) / 2 * m_A) / m_Divisor; m_HalfC = m_C / 2; m_HalfD = m_D / 2; m_InvSpread = T(0.5) / m_Spread; m_FullSpread = M_2PI * m_Spread; m_SpreadUint = uint(m_Spread); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_R, prefix + "cpow2_r", 1)); m_Params.push_back(ParamWithName(&m_A, prefix + "cpow2_a")); m_Params.push_back(ParamWithName(&m_Divisor, prefix + "cpow2_divisor", 1, eParamType::INTEGER_NONZERO)); m_Params.push_back(ParamWithName(&m_Spread, prefix + "cpow2_spread", 1, eParamType::INTEGER, 1, T(0x7FFFFFFF))); m_Params.push_back(ParamWithName(true, &m_C, prefix + "cpow2_c"));//Precalc. m_Params.push_back(ParamWithName(true, &m_HalfC, prefix + "cpow2_halfc")); m_Params.push_back(ParamWithName(true, &m_D, prefix + "cpow2_d")); m_Params.push_back(ParamWithName(true, &m_HalfD, prefix + "cpow2_halfd")); m_Params.push_back(ParamWithName(true, &m_Ang, prefix + "cpow2_ang")); m_Params.push_back(ParamWithName(true, &m_InvSpread, prefix + "cpow2_inv_spread")); m_Params.push_back(ParamWithName(true, &m_FullSpread, prefix + "cpow2_full_spread")); } private: T m_R; T m_A; T m_Divisor; T m_Spread; uint m_SpreadUint;//Precalc. T m_C; T m_HalfC; T m_D; T m_HalfD; T m_Ang; T m_InvSpread; T m_FullSpread; }; MAKEPREPOSTVAR(Hemisphere, hemisphere, HEMISPHERE) MAKEPREPOSTPARVAR(Epispiral, epispiral, EPISPIRAL) MAKEPREPOSTPARVAR(Bwraps, bwraps, BWRAPS) MAKEPREPOSTPARVAR(BwrapsRand, bwraps_rand, BWRAPS_RAND) MAKEPREPOSTVARASSIGN(BlurCircle, blur_circle, BLUR_CIRCLE, eVariationAssignType::ASSIGNTYPE_SUM) MAKEPREPOSTPARVAR(BlurZoom, blur_zoom, BLUR_ZOOM) MAKEPREPOSTPARVAR(BlurPixelize, blur_pixelize, BLUR_PIXELIZE) MAKEPREPOSTPARVAR(Crop, crop, CROP) MAKEPREPOSTPARVAR(BCircle, bcircle, BCIRCLE) MAKEPREPOSTPARVAR(BlurLinear, blur_linear, BLUR_LINEAR) MAKEPREPOSTPARVARASSIGN(BlurSquare, blur_square, BLUR_SQUARE, eVariationAssignType::ASSIGNTYPE_SUM) MAKEPREPOSTVAR(Flatten, flatten, FLATTEN) MAKEPREPOSTVARASSIGN(Zblur, zblur, ZBLUR, eVariationAssignType::ASSIGNTYPE_SUM) MAKEPREPOSTVARASSIGN(Blur3D, blur3D, BLUR3D, eVariationAssignType::ASSIGNTYPE_SUM) MAKEPREPOSTVAR(ZScale, zscale, ZSCALE) MAKEPREPOSTVARASSIGN(ZTranslate, ztranslate, ZTRANSLATE, eVariationAssignType::ASSIGNTYPE_SUM) MAKEPREPOSTVAR(ZCone, zcone, ZCONE) MAKEPREPOSTVAR(Spherical3D, Spherical3D, SPHERICAL3D) MAKEPREPOSTPARVAR(Curl3D, curl3D, CURL3D) MAKEPREPOSTPARVAR(Disc3D, disc3d, DISC3D) MAKEPREPOSTPARVAR(Boarders2, boarders2, BOARDERS2) MAKEPREPOSTPARVAR(Cardioid, cardioid, CARDIOID) MAKEPREPOSTPARVAR(Checks, checks, CHECKS) MAKEPREPOSTPARVAR(Circlize, circlize, CIRCLIZE) MAKEPREPOSTPARVAR(Circlize2, circlize2, CIRCLIZE2) MAKEPREPOSTPARVAR(CosWrap, coswrap, COS_WRAP) MAKEPREPOSTVAR(DeltaA, deltaa, DELTA_A) MAKEPREPOSTPARVAR(Expo, expo, EXPO) MAKEPREPOSTPARVAR(Extrude, extrude, EXTRUDE) MAKEPREPOSTVAR(FDisc, fdisc, FDISC) MAKEPREPOSTPARVAR(Fibonacci, fibonacci, FIBONACCI) MAKEPREPOSTPARVAR(Fibonacci2, fibonacci2, FIBONACCI2) MAKEPREPOSTPARVAR(Glynnia, glynnia, GLYNNIA) MAKEPREPOSTPARVAR(Glynnia2, glynnia2, GLYNNIA2) MAKEPREPOSTVAR(GridOut, gridout, GRIDOUT) MAKEPREPOSTPARVAR(Hole, hole, HOLE) MAKEPREPOSTPARVAR(Hypertile, hypertile, HYPERTILE) MAKEPREPOSTPARVAR(Hypertile1, hypertile1, HYPERTILE1) MAKEPREPOSTPARVAR(Hypertile2, hypertile2, HYPERTILE2) MAKEPREPOSTPARVAR(Hypertile3D, hypertile3D, HYPERTILE3D) MAKEPREPOSTPARVAR(Hypertile3D1, hypertile3D1, HYPERTILE3D1) MAKEPREPOSTPARVAR(Hypertile3D2, hypertile3D2, HYPERTILE3D2) MAKEPREPOSTPARVAR(IDisc, idisc, IDISC) MAKEPREPOSTPARVAR(Julian2, julian2, JULIAN2) MAKEPREPOSTPARVAR(JuliaQ, juliaq, JULIAQ) MAKEPREPOSTPARVAR(Murl, murl, MURL) MAKEPREPOSTPARVAR(Murl2, murl2, MURL2) MAKEPREPOSTPARVAR(NPolar, npolar, NPOLAR) MAKEPREPOSTPARVAR(Ortho, ortho, ORTHO) MAKEPREPOSTPARVAR(Poincare, poincare, POINCARE) MAKEPREPOSTPARVAR(Poincare2, poincare2, POINCARE2) MAKEPREPOSTPARVAR(Poincare3D, poincare3D, POINCARE3D) MAKEPREPOSTPARVAR(Polynomial, polynomial, POLYNOMIAL) MAKEPREPOSTPARVAR(PSphere, psphere, PSPHERE) MAKEPREPOSTPARVAR(Rational3, rational3, RATIONAL3) MAKEPREPOSTPARVAR(Ripple, ripple, RIPPLE) MAKEPREPOSTPARVAR(Sigmoid, sigmoid, SIGMOID) MAKEPREPOSTPARVAR(SinusGrid, sinusgrid, SINUS_GRID) MAKEPREPOSTPARVAR(Stwin, stwin, STWIN) MAKEPREPOSTVAR(TwoFace, twoface, TWO_FACE) MAKEPREPOSTPARVAR(Unpolar, unpolar, UNPOLAR) MAKEPREPOSTPARVAR(WavesN, wavesn, WAVESN) MAKEPREPOSTPARVAR(XHeart, xheart, XHEART) MAKEPREPOSTPARVAR(Barycentroid, barycentroid, BARYCENTROID) MAKEPREPOSTPARVAR(BiSplit, bisplit, BISPLIT) MAKEPREPOSTVAR(Crescents, crescents, CRESCENTS) MAKEPREPOSTVAR(Mask, mask, MASK) MAKEPREPOSTPARVAR(Cpow2, cpow2, CPOW2) }