diff --git a/Builds/MSVC/Installer/Product.wxs b/Builds/MSVC/Installer/Product.wxs index faf01c4..c6f57a8 100644 --- a/Builds/MSVC/Installer/Product.wxs +++ b/Builds/MSVC/Installer/Product.wxs @@ -12,7 +12,7 @@ - + diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index d9ec131..7c7c1ad 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -22,14 +22,14 @@ static void parallel_for(size_t start, size_t end, size_t parlevel, std::functio for (size_t i = 0; i < ct; i++) { - threads.push_back(std::thread([&, i] + threads.push_back(std::thread([&](size_t _i, size_t _ct) { - const auto chunkStart = chunkSize* i; - const auto chunkEnd = std::min(chunkStart + chunkSize, end); + const auto chunkStart = chunkSize * _i; + const auto chunkEnd = _i == _ct - 1 ? end : std::min(chunkStart + chunkSize, end); for (size_t j = chunkStart; j < chunkEnd; j++) func(j); - })); + }, i, ct)); } EmberNs::Join(threads); diff --git a/Source/Ember/EmberPch.h b/Source/Ember/EmberPch.h index 00c90f4..9855df0 100644 --- a/Source/Ember/EmberPch.h +++ b/Source/Ember/EmberPch.h @@ -41,7 +41,7 @@ #include #ifdef __APPLE__ #include - #include + #include #else #include #endif diff --git a/Source/Ember/EmberToXml.cpp b/Source/Ember/EmberToXml.cpp index f370b40..bba4534 100644 --- a/Source/Ember/EmberToXml.cpp +++ b/Source/Ember/EmberToXml.cpp @@ -502,6 +502,7 @@ string EmberToXml::ToString(Xform& xform, size_t xformCount, bool isFinal, { size_t i, j; ostringstream os; + os << std::fixed << std::setprecision(8); if (doMotion) { diff --git a/Source/Ember/Isaac.h b/Source/Ember/Isaac.h index 3984ae5..22fc0f2 100644 --- a/Source/Ember/Isaac.h +++ b/Source/Ember/Isaac.h @@ -224,7 +224,7 @@ public: #ifdef ISAAC_FLAM3_DEBUG return (Rand() & 0xfffffff) / (floatType)0xfffffff; #else - return Frand(static_cast(0), static_cast(1)); + return static_cast(Rand()) / static_cast(std::numeric_limits::max()); #endif } diff --git a/Source/Ember/Utils.h b/Source/Ember/Utils.h index 5f6830d..0ce97aa 100644 --- a/Source/Ember/Utils.h +++ b/Source/Ember/Utils.h @@ -900,11 +900,17 @@ static bool EndsWith(const std::string& str, const std::string& suffix) /// /// The string to test /// The string to test for +/// True to do a case insensitive comparisoin, else case sensitive. Default: false. /// True if str starts with suffix, else false. -static bool StartsWith(const std::string& str, const std::string& prefix) +static bool StartsWith(const std::string& str, const std::string& prefix, bool ignoreCase = false) { - return str.size() >= prefix.size() && - str.compare(0, prefix.size(), prefix) == 0; + if (ignoreCase) + { + return str.size() >= prefix.size() && + (_strnicmp(str.c_str(), prefix.c_str(), std::min(str.length(), prefix.length())) == 0); + } + else + return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; } /// diff --git a/Source/Ember/Variation.h b/Source/Ember/Variation.h index 622b61d..7a88e32 100644 --- a/Source/Ember/Variation.h +++ b/Source/Ember/Variation.h @@ -1757,7 +1757,7 @@ protected: eVariationType m_VarType;//The type of variation: regular, pre or post. eVariationAssignType m_PrePostAssignType;//Whether to assign the results for pre/post, or sum them. -private: +protected: bool m_NeedPrecalcSumSquares;//Whether this variation uses the precalc sum squares value in its calculations. bool m_NeedPrecalcSqrtSumSquares;//Whether it uses the sqrt precalc sum squares value in its calculations. bool m_NeedPrecalcAngles;//Whether it uses the precalc sin and cos values in its calculations. diff --git a/Source/Ember/Variations01.h b/Source/Ember/Variations01.h index e695268..79523f5 100644 --- a/Source/Ember/Variations01.h +++ b/Source/Ember/Variations01.h @@ -726,13 +726,23 @@ template class JuliaVariation : public Variation { public: - JuliaVariation(T weight = 1.0) : Variation("julia", eVariationId::VAR_JULIA, weight, true, true, false, true) { } + using Variation::m_NeedPrecalcSqrtSumSquares; + JuliaVariation(T weight = 1.0) : Variation("julia", eVariationId::VAR_JULIA, weight, true, false, false, true) + { + m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; + } VARCOPY(JuliaVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T r = m_Weight * std::sqrt(helper.m_PrecalcSqrtSumSquares); + T r; + + if (Compat::m_Compat) + r = m_Weight * std::sqrt(helper.m_PrecalcSqrtSumSquares); + else + r = m_Weight * std::exp(T(0.25) * std::log(helper.m_PrecalcSumSquares)); + T a = T(0.5) * helper.m_PrecalcAtanxy; if (rand.RandBit()) @@ -747,9 +757,14 @@ public: { ostringstream ss; string weight = WeightDefineString(); - ss << "\t{\n" - << "\t\treal_t r = " << weight << " * sqrt(precalcSqrtSumSquares);\n" - << "\t\treal_t a = (real_t)(0.5) * precalcAtanxy;\n" + ss << "\t{\n"; + + if (Compat::m_Compat) + ss << "\t\treal_t r = " << weight << " * sqrt(precalcSqrtSumSquares);\n"; + else + ss << "\t\treal_t r = " << weight << " * exp((real_t)(0.25) * log(precalcSumSquares));\n"; + + ss << "\t\treal_t a = (real_t)(0.5) * precalcAtanxy;\n" << "\n" << "\t\tif (MwcNext(mwc) & 1)\n" << "\t\t a += MPI;\n" @@ -760,6 +775,11 @@ public: << "\t}\n"; return ss.str(); } + + virtual void Precalc() override + { + m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; + } }; /// @@ -1407,15 +1427,23 @@ public: { T a = helper.m_PrecalcAtanxy; T r = m_Weight * helper.m_PrecalcSqrtSumSquares; - T t = a + m_Fan2Y - m_Fan2Dx * int((a + m_Fan2Y) / m_Fan2Dx); - if (t > m_Fan2Dx2) + if (std::fmod(a + m_Fan2Y, m_Fan2Dx) > m_Fan2Dx2) a = a - m_Fan2Dx2; else a = a + m_Fan2Dx2; - helper.Out.x = r * std::sin(a); - helper.Out.y = r * std::cos(a); + if (Compat::m_Compat) + { + helper.Out.x = r * std::sin(a); + helper.Out.y = r * std::cos(a); + } + else + { + helper.Out.x = r * std::cos(a); + helper.Out.y = r * std::sin(a); + } + helper.Out.z = m_Weight * helper.In.z; } @@ -1432,18 +1460,27 @@ public: string dx2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = precalcAtanxy;\n" - << "\t\treal_t r = " << weight << " * precalcSqrtSumSquares;\n" - << "\t\treal_t t = a + " << fan2Y << " - " << dx << " * (int)((a + " << fan2Y << ") / " << dx << ");\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t r = weight * precalcSqrtSumSquares;\n" + << "\t\treal_t dx2 = " << dx2 << ";\n" << "\n" - << "\t\tif (t > " << dx2 << ")\n" - << "\t\t a = a - " << dx2 << ";\n" + << "\t\tif (fmod(a + " << fan2Y << ", " << dx << ") > dx2)\n" + << "\t\t a = a - dx2;\n" << "\t\telse\n" - << "\t\t a = a + " << dx2 << ";\n" - << "\n" - << "\t\tvOut.x = r * sin(a);\n" - << "\t\tvOut.y = r * cos(a);\n" - << "\t\tvOut.z = " << weight << " * vIn.z;\n" - << "\t}\n"; + << "\t\t a = a + dx2;\n" + << "\n"; + + if (Compat::m_Compat) + ss << "\t\tvOut.x = r * sin(a);\n" + << "\t\tvOut.y = r * cos(a);\n" + << "\t\tvOut.z = weight * vIn.z;\n" + << "\t}\n"; + else + ss << "\t\tvOut.x = r * cos(a);\n" + << "\t\tvOut.y = r * sin(a);\n" + << "\t\tvOut.z = weight * vIn.z;\n" + << "\t}\n"; + return ss.str(); } @@ -1464,8 +1501,8 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Fan2X, prefix + "fan2_x")); - m_Params.push_back(ParamWithName(&m_Fan2Y, prefix + "fan2_y")); + m_Params.push_back(ParamWithName(&m_Fan2X, prefix + "fan2_x", T(0.70710678118654752440084436210485))); + m_Params.push_back(ParamWithName(&m_Fan2Y, prefix + "fan2_y", T(-0.70710678118654752440084436210485))); m_Params.push_back(ParamWithName(true, &m_Fan2Dx, prefix + "fan2_dx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Fan2Dx2, prefix + "fan2_dx2")); } @@ -1677,10 +1714,9 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T d = Zeps(m_Dist - helper.In.y * m_Vsin); - T t = 1 / d; - helper.Out.x = m_Weight * m_Dist * helper.In.x * t; - helper.Out.y = m_Weight * m_VfCos * helper.In.y * t; + T d = m_Weight / Zeps(m_Dist - helper.In.y * m_Vsin); + helper.Out.x = d * m_Dist * helper.In.x; + helper.Out.y = d * m_VfCos * helper.In.y; helper.Out.z = DefaultZ(helper); } @@ -1696,11 +1732,10 @@ public: string vSin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string vfCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t d = Zeps(" << dist << " - vIn.y * " << vSin << ");\n" - << "\t\treal_t t = (real_t)(1.0) / d;\n" + << "\t\treal_t d = " << weight << " / Zeps(" << dist << " - vIn.y * " << vSin << "); \n" << "\n" - << "\t\tvOut.x = (" << weight << " * " << dist << " * vIn.x * t);\n" - << "\t\tvOut.y = (" << weight << " * " << vfCos << " * vIn.y * t);\n" + << "\t\tvOut.x = d * " << dist << " * vIn.x;\n" + << "\t\tvOut.y = d * " << vfCos << " * vIn.y;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -1756,7 +1791,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T tempr = rand.Frand01() * M_2PI; - T r = m_Weight * rand.Frand01(); + T r = rand.Frand01() * m_Weight; helper.Out.x = helper.In.x * r * std::cos(tempr); helper.Out.y = helper.In.y * r * std::sin(tempr); helper.Out.z = m_Weight * helper.In.z; @@ -1768,7 +1803,7 @@ public: string weight = WeightDefineString(); ss << "\t{\n" << "\t\treal_t tempr = MwcNext01(mwc) * M_2PI;\n" - << "\t\treal_t r = " << weight << " * MwcNext01(mwc);\n" + << "\t\treal_t r = MwcNext01(mwc) * " << weight << ";\n" << "\n" << "\t\tvOut.x = vIn.x * r * cos(tempr);\n" << "\t\tvOut.y = vIn.y * r * sin(tempr);\n" @@ -1794,10 +1829,21 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T tempr = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(size_t(m_Rn))) / m_Power; + T a; T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); - helper.Out.x = r * std::cos(tempr); - helper.Out.y = r * std::sin(tempr); + + if (Compat::m_Compat) + { + a = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(size_t(m_Rn))) / m_Power; + } + else + { + int root = (int)(m_Power * rand.Frand01()); + a = (helper.m_PrecalcAtanyx + root * M_2PI) / m_Power; + } + + helper.Out.x = r * std::cos(a); + helper.Out.y = r * std::sin(a); helper.Out.z = m_Weight * helper.In.z; } @@ -1813,12 +1859,21 @@ public: string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\tint tRnd = (int)(" << rn << " * MwcNext01(mwc));\n" - << "\t\treal_t tempr = fma(M_2PI, (real_t)tRnd, precalcAtanyx) / " << power << ";\n" - << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" - << "\n" - << "\t\tvOut.x = r * cos(tempr);\n" - << "\t\tvOut.y = r * sin(tempr);\n" + << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cn << ");\n"; + + if (Compat::m_Compat) + { + ss << "\t\treal_t a = (precalcAtanyx + M_2PI * (int)(" << rn << " * MwcNext01(mwc))) / " << power << ";\n"; + } + else + { + ss << "\t\tint root = (int)(" << power << " * MwcNext01(mwc));\n" + << "\t\treal_t a = (precalcAtanyx + root * M_2PI) / " << power << ";\n"; + } + + ss << "\n" + << "\t\tvOut.x = r * cos(a);\n" + << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = " << weight << " * vIn.z;\n" << "\t}\n"; return ss.str(); @@ -1828,7 +1883,7 @@ public: { m_Power = Zeps(m_Power); m_Rn = std::abs(m_Power); - m_Cn = m_Dist / m_Power / 2; + m_Cn = m_Dist / m_Power * T(0.5); } virtual void Random(QTIsaac& rand) override @@ -1843,7 +1898,7 @@ protected: string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Dist, prefix + "julian_dist", 1)); - m_Params.push_back(ParamWithName(&m_Power, prefix + "julian_power", 1, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_Power, prefix + "julian_power", 1)); m_Params.push_back(ParamWithName(true, &m_Rn, prefix + "julian_rn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "julian_cn")); } @@ -1871,26 +1926,29 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - int rnd = int(m_Rn * rand.Frand01()); - T tempr, r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); + T a, r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); - if ((rnd & 1) == 0) - tempr = (M_2PI * rnd + helper.m_PrecalcAtanyx) / m_Power; + if (Compat::m_Compat) + { + int rnd = int(m_Rn * rand.Frand01()); + + if ((rnd & 1) == 0) + a = (M_2PI * rnd + helper.m_PrecalcAtanyx) / m_Power; + else + a = (M_2PI * rnd - helper.m_PrecalcAtanyx) / m_Power; + } else - tempr = (M_2PI * rnd - helper.m_PrecalcAtanyx) / m_Power; + { + auto root = Floor(m_Power * rand.Frand01()); + auto root_div2 = Floor(root * T(0.5)); + auto root_mod2 = root - root_div2 * 2; + T root_scale = T(root_mod2 == 1 ? -1 : 1); + a = (helper.m_PrecalcAtanyx * root_scale + root * M_2PI) / Zeps(m_Power); + } - helper.Out.x = r * std::cos(tempr); - helper.Out.y = r * std::sin(tempr); + helper.Out.x = r * std::cos(a); + helper.Out.y = r * std::sin(a); helper.Out.z = m_Weight * helper.In.z; - //int rnd = (int)(m_Rn * rand.Frand01()); - //T tempr, r; - //if ((rnd & 1) == 0) - // tempr = (2 * T(M_PI) * (int)(m_Rn * rand.Frand01()) + helper.m_PrecalcAtanyx) / m_Power;//Fixed to get new random rather than use rnd from above.//SMOULDER - //else - // tempr = (2 * T(M_PI) * (int)(m_Rn * rand.Frand01()) - helper.m_PrecalcAtanyx) / m_Power; - //r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn); - //helper.Out.x = r * cos(tempr); - //helper.Out.y = r * sin(tempr); } virtual string OpenCLString() const override @@ -1905,40 +1963,40 @@ public: string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\tint rnd = (int)(" << rn << " * MwcNext01(mwc));\n" - << "\t\treal_t tempr, r;\n" - << "\n" - << "\t\tif ((rnd & 1) == 0)\n" - << "\t\t tempr = fma(M_2PI, (real_t)rnd, precalcAtanyx) / " << power << ";\n" - << "\t\telse\n" - << "\t\t tempr = fma(M_2PI, (real_t)rnd, -precalcAtanyx) / " << power << ";\n" - << "\n" - << "\t\tr = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" - << "\n" - << "\t\tvOut.x = r * cos(tempr);\n" - << "\t\tvOut.y = r * sin(tempr);\n" + << "\t\treal_t a;\n" + << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" + << "\t\treal_t power = " << power << ";\n" + << "\n"; + + if (Compat::m_Compat) + { + ss << "\t\tint rnd = (int)(" << rn << " * MwcNext01(mwc));\n" + << "\n" + << "\t\tif ((rnd & 1) == 0)\n" + << "\t\t a = fma(M_2PI, (real_t)rnd, precalcAtanyx) / power;\n" + << "\t\telse\n" + << "\t\t a = fma(M_2PI, (real_t)rnd, -precalcAtanyx) / power;\n" + << "\n"; + } + else + { + ss << "\t\tint root = (int)floor(power * MwcNext01(mwc));\n" + << "\t\tint root_div2 = (int)floor(root * (real_t)(0.5));\n" + << "\t\tint root_mod2 = root - root_div2 * 2;\n" + << "\t\tint root_scale = (real_t)(root_mod2 == 1 ? -1.0 : 1.0);\n" + << "\t\ta = (precalcAtanyx * root_scale + root * M_2PI) / power;\n"; + } + + ss << "\t\tvOut.x = r * cos(a);\n" + << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = " << weight << " * vIn.z;\n" << "\t}\n"; - //ss << "\t{\n" - // << "\t\tint rnd = (int)(" << rn << " * MwcNext01(mwc));\n" - // << "\t\treal_t tempr, r;\n" - // << "\n" - // << "\t\tif ((rnd & 1) == 0)\n" - // << "\t\t tempr = (2 * M_PI * (int)(" << rn << " * MwcNext01(mwc)) + precalcAtanyx) / " << power << ";\n"//Fixed to get new random rather than use rnd from above.//SMOULDER - // << "\t\telse\n" - // << "\t\t tempr = (2 * M_PI * (int)(" << rn << " * MwcNext01(mwc)) - precalcAtanyx) / " << power << ";\n" - // << "\n" - // << "\t\tr = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" - // << "\n" - // << "\t\tvOut.x = r * cos(tempr);\n" - // << "\t\tvOut.y = r * sin(tempr);\n" - // << "\t\tvOut.z = " << weight << " * vIn.z;\n" - // << "\t}\n"; return ss.str(); } virtual void Precalc() override { + m_Power = Zeps(m_Power); m_Rn = std::abs(m_Power); m_Cn = m_Dist / m_Power / 2; } @@ -2361,7 +2419,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T re = 1 + m_C1 * helper.In.x + m_C2 * (SQR(helper.In.x) - SQR(helper.In.y)); - T im = m_C1 * helper.In.y + m_C22 * helper.In.x * helper.In.y; + T im = (m_C1 + m_C22 * helper.In.x) * helper.In.y; T r = m_Weight / Zeps(SQR(re) + SQR(im)); helper.Out.x = (helper.In.x * re + helper.In.y * im) * r; helper.Out.y = (helper.In.y * re - helper.In.x * im) * r; @@ -2380,7 +2438,7 @@ public: string c22 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t re = (real_t)(1.0) + " << c1 << " * vIn.x + " << c2 << " * fma(vIn.x, vIn.x, -SQR(vIn.y));\n" - << "\t\treal_t im = fma(" << c1 << ", vIn.y, " << c22 << " * vIn.x * vIn.y);\n" + << "\t\treal_t im = fma(" << c22 << ", vIn.x, " << c1 << ") * vIn.y;\n" << "\t\treal_t r = " << weight << " / Zeps(fma(re, re, SQR(im)));\n" << "\n" << "\t\tvOut.x = fma(vIn.x, re, vIn.y * im) * r;\n" @@ -2928,7 +2986,18 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T r = m_Weight / Zeps(std::abs((helper.In.x - helper.In.y) * (helper.In.x + helper.In.y))); + T r; + + if (Compat::m_Compat) + { + r = m_Weight / Zeps(std::abs((helper.In.x - helper.In.y) * (helper.In.x + helper.In.y))); + } + else + { + T s = Zeps(Sqr(helper.In.x) - Sqr(helper.In.y)); + r = m_Weight / s; + } + helper.Out.x = helper.In.x * r; helper.Out.y = helper.In.y * r; helper.Out.z = m_Weight * helper.In.z; @@ -2939,12 +3008,23 @@ public: ostringstream ss; string weight = WeightDefineString(); ss << "\t{\n" - << "\t\treal_t r = " << weight << " /Zeps(fabs((vIn.x - vIn.y) * (vIn.x + vIn.y)));\n" - << "\n" - << "\t\tvOut.x = vIn.x * r;\n" - << "\t\tvOut.y = vIn.y * r;\n" - << "\t\tvOut.z = " << weight << " * vIn.z;\n" - << "\t}\n"; + << "\t\treal_t r;\n"; + + if (Compat::m_Compat) + { + ss << "\t\tr = " << weight << " / Zeps(fabs((vIn.x - vIn.y) * (vIn.x + vIn.y)));\n"; + } + else + { + ss << "\t\treal_t s = Zeps(SQR(vIn.x) - SQR(vIn.y));\n" + << "\t\tr = " << weight << " / s;\n"; + } + + ss << "\n" + << "\t\tvOut.x = vIn.x * r;\n" + << "\t\tvOut.y = vIn.y * r;\n" + << "\t\tvOut.z = " << weight << " * vIn.z;\n" + << "\t}\n"; return ss.str(); } @@ -3534,10 +3614,11 @@ public: const T f = t + x2; const T g = t - x2; + const T foverg = f / Zeps(g); - if ((g == 0) || (f / g <= 0)) + if ((g == 0) || (foverg <= 0)) { - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) { helper.Out.x = 0; helper.Out.y = 0; @@ -3552,7 +3633,7 @@ public: } else { - helper.Out.x = m_V4 * std::log((t + x2) / Zeps(t - x2)); + helper.Out.x = m_V4 * std::log(foverg); helper.Out.y = m_V * y; helper.Out.z = m_Weight * helper.In.z; } @@ -3583,11 +3664,12 @@ public: << "\n" << "\t\treal_t f = t + x2;\n" << "\t\treal_t g = t - x2;\n" + << "\t\treal_t foverg = f / Zeps(g);\n" << "\n"; - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) { - ss << "\t\tif ((g == 0) || (f / g <= 0))\n" + ss << "\t\tif ((g == 0) || (foverg <= 0))\n" << "\t\t{\n" << "\t\t vOut.x = 0;\n" << "\t\t vOut.y = 0;\n" @@ -3596,7 +3678,7 @@ public: } else { - ss << "\t\tif ((g == 0) || (f / g <= 0))\n" + ss << "\t\tif ((g == 0) || (foverg <= 0))\n" << "\t\t{\n" << "\t\t vOut.x = vIn.x;\n" << "\t\t vOut.y = vIn.y;\n" @@ -3606,8 +3688,8 @@ public: ss << "\t\telse\n" << "\t\t{\n" - << "\t\t vOut.x = (" << v4 << " * log((t + x2) / Zeps(t - x2)));\n" - << "\t\t vOut.y = (" << v << " * y);\n" + << "\t\t vOut.x = " << v4 << " * log(foverg);\n" + << "\t\t vOut.y = " << v << " * y;\n" << "\t\t vOut.z = " << weight << " * vIn.z;\n" << "\t\t}\n" << "\t}\n"; @@ -3616,7 +3698,7 @@ public: virtual void Precalc() override { - m_S = -T(M_PI_2) * m_Shift;; + m_S = -T(M_PI_2) * m_Shift; m_V = m_Weight * T(M_2_PI); m_V4 = m_Weight * T(0.25) * T(M_2_PI); } @@ -3631,19 +3713,6 @@ public: return vector { "Zeps" }; } - virtual bool SetParamVal(const char* name, T val) override - { - if (!_stricmp(name, "bipolar_shift")) - { - T temp = VarFuncs::Fabsmod(T(0.5) * (val + 1)); - m_Shift = 2 * temp - 1; - Precalc(); - return true; - } - - return ParametricVariation::SetParamVal(name, val); - } - protected: void Init() { @@ -3829,8 +3898,8 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { T invCellSize = 1 / m_Size; - T x = std::floor(helper.In.x * invCellSize);//Calculate input cell. Note that int cast is omitted here. See below. - T y = std::floor(helper.In.y * invCellSize); + T x = T(Floor(helper.In.x * invCellSize));//Calculate input cell. Note that int cast is omitted here. See below. + T y = T(Floor(helper.In.y * invCellSize)); T dx = helper.In.x - x * m_Size;//Offset from cell origin. T dy = helper.In.y - y * m_Size; @@ -4135,11 +4204,17 @@ public: T r1 = std::sqrt(tmp + tmp2); T r2 = std::sqrt(tmp - tmp2); T xmax = Zeps((r1 + r2) * T(0.5)); - T a1 = std::log(xmax + std::sqrt(xmax - 1)); - T a2 = -std::acos(Clamp(helper.In.x / xmax, -1, 1)); - T w = m_Weight / T(11.57034632);//This is an interesting magic number. + T logs = std::log(xmax + std::sqrt(xmax - 1)); + T a2; + + if (Compat::m_Compat) + a2 = -std::acos(Clamp(helper.In.x / xmax, -1, 1)); + else + a2 = std::acos(helper.In.x / xmax); + + T w = m_Weight / T(11.57034632);//2 / e^pi. T snv, csv, snhu, cshu; - sincos(a1, &snv, &csv); + sincos(logs, &snv, &csv); snhu = std::sinh(a2); cshu = std::cosh(a2); @@ -4161,11 +4236,17 @@ public: << "\t\treal_t r1 = sqrt(tmp + tmp2);\n" << "\t\treal_t r2 = sqrt(tmp - tmp2);\n" << "\t\treal_t xmax = Zeps((r1 + r2) * (real_t)(0.5));\n" - << "\t\treal_t a1 = log(xmax + sqrt(xmax - (real_t)(1.0)));\n" - << "\t\treal_t a2 = -acos(clamp(vIn.x / xmax, -(real_t)(1.0), (real_t)(1.0)));\n" - << "\t\treal_t w = " << weight << " / (real_t)(11.57034632);\n" - << "\t\treal_t snv = sin(a1);\n" - << "\t\treal_t csv = cos(a1);\n" + << "\t\treal_t logs = log(xmax + sqrt(xmax - (real_t)(1.0)));\n" + << "\t\treal_t a2;\n"; + + if (Compat::m_Compat) + ss << "\t\ta2 = -acos(clamp(vIn.x / xmax, -(real_t)(1.0), (real_t)(1.0)));\n"; + else + ss << "\t\ta2 = acos(vIn.x / xmax);\n"; + + ss << "\t\treal_t w = " << weight << " / (real_t)(11.57034632);\n" + << "\t\treal_t snv = sin(logs);\n" + << "\t\treal_t csv = cos(logs);\n" << "\t\treal_t snhu = sinh(a2);\n" << "\t\treal_t cshu = cosh(a2);\n" << "\t\tif (vIn.y > 0)\n" @@ -4197,7 +4278,7 @@ public: PARVARCOPY(EllipticVariation) - //An improved version which was posted in the Discord chat by user Claude which was helps with rounding errors. + //An improved version which was posted in the Discord chat by user Claude which helps with rounding errors. //Note that for this to work, a "bad value" had to be changed from 1e10 and -1e10 to 1e50 and -1e50. //For this to be correct, it must always use double. So there is no point in switching precisions when using this variation. virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override @@ -4402,16 +4483,29 @@ template class EscherVariation : public ParametricVariation { public: - EscherVariation(T weight = 1.0) : ParametricVariation("escher", eVariationId::VAR_ESCHER, weight, true, false, false, false, true) + using Variation::m_NeedPrecalcAtanXY; + using Variation::m_NeedPrecalcAtanYX; + EscherVariation(T weight = 1.0) : ParametricVariation("escher", eVariationId::VAR_ESCHER, weight, true, false, false, true, true) { Init(); + + if (Compat::m_Compat) + { + m_NeedPrecalcAtanXY = false; + m_NeedPrecalcAtanYX = true; + } + else + { + m_NeedPrecalcAtanXY = true; + m_NeedPrecalcAtanYX = false; + } } PARVARCOPY(EscherVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T a = helper.m_PrecalcAtanyx; + T a = Compat::m_Compat ? helper.m_PrecalcAtanyx : helper.m_PrecalcAtanxy; T lnr = T(0.5) * std::log(helper.m_PrecalcSumSquares); T m = m_Weight * std::exp(m_C * lnr - m_D * a); T n = m_C * a + m_D * lnr; @@ -4431,7 +4525,7 @@ public: string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t a = precalcAtanyx;\n" + << "\t\treal_t a = " << (Compat::m_Compat ? "precalcAtanyx" : "precalcAtanxy") << ";\n" << "\t\treal_t lnr = (real_t)(0.5) * log(precalcSumSquares);\n" << "\t\treal_t m = " << weight << " * exp(fma(" << c << ", lnr, -(" << d << " * a)));\n" << "\t\treal_t n = fma(" << c << ", a, " << d << " * lnr);\n" @@ -4448,23 +4542,22 @@ public: sincos(m_Beta, &m_D, &m_C); m_C = T(0.5) * (1 + m_C); m_D = T(0.5) * m_D; + + if (Compat::m_Compat) + { + m_NeedPrecalcAtanXY = false; + m_NeedPrecalcAtanYX = true; + } + else + { + m_NeedPrecalcAtanXY = true; + m_NeedPrecalcAtanYX = false; + } } virtual void Random(QTIsaac& rand) override { - SetParamVal("escher_beta", T(M_PI) * rand.Frand01()); - } - - virtual bool SetParamVal(const char* name, T val) override - { - if (!_stricmp(name, "escher_beta")) - { - m_Beta = VarFuncs::Fabsmod((val + T(M_PI)) / (2 * T(M_PI))) * 2 * T(M_PI) - T(M_PI); - Precalc(); - return true; - } - - return ParametricVariation::SetParamVal(name, val); + m_Beta = T(M_PI) * rand.Frand01(); } protected: @@ -4472,7 +4565,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Beta, prefix + "escher_beta")); + m_Params.push_back(ParamWithName(&m_Beta, prefix + "escher_beta", 3)); m_Params.push_back(ParamWithName(true, &m_C, prefix + "escher_beta_c"));//Precalc. m_Params.push_back(ParamWithName(true, &m_D, prefix + "escher_beta_d")); } @@ -4610,18 +4703,6 @@ public: return vector { "Zeps" }; } - virtual bool SetParamVal(const char* name, T val) override - { - if (!_stricmp(name, "lazysusan_spin")) - { - m_Spin = VarFuncs::Fabsmod(val / T(M_2PI)) * T(M_2PI); - this->Precalc(); - return true; - } - - return ParametricVariation::SetParamVal(name, val); - } - virtual void Random(QTIsaac& rand) override { m_X = 2 * rand.Frand11(); @@ -5020,7 +5101,7 @@ protected: m_Params.push_back(ParamWithName(&m_FrequencyY, prefix + "oscilloscope2_frequencyy", T(M_PI))); m_Params.push_back(ParamWithName(&m_Amplitude, prefix + "oscilloscope2_amplitude", 1)); m_Params.push_back(ParamWithName(&m_Perturbation, prefix + "oscilloscope2_perturbation", 1)); - m_Params.push_back(ParamWithName(&m_Damping, prefix + "oscilloscope2_damping", 0, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Damping, prefix + "oscilloscope2_damping", 0)); m_Params.push_back(ParamWithName(true, &m_Tpf, prefix + "oscilloscope2_tpf"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Tpf2, prefix + "oscilloscope2_tpf2")); } @@ -6142,7 +6223,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - helper.Out.x = m_Weight * std::log(helper.m_PrecalcSumSquares) * m_Denom; + helper.Out.x = std::log(helper.m_PrecalcSumSquares) * m_Denom; helper.Out.y = m_Weight * helper.m_PrecalcAtanyx; helper.Out.z = m_Weight * helper.In.z; } @@ -6157,7 +6238,7 @@ public: string base = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string denom = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\tvOut.x = " << weight << " * log(precalcSumSquares) * " << denom << ";\n" + << "\t\tvOut.x = log(precalcSumSquares) * " << denom << ";\n" << "\t\tvOut.y = " << weight << " * precalcAtanyx;\n" << "\t\tvOut.z = " << weight << " * vIn.z;\n" << "\t}\n"; @@ -6166,7 +6247,7 @@ public: virtual void Precalc() override { - m_Denom = T(0.5) / std::log(m_Base); + m_Denom = m_Weight * T(0.5) / std::log(m_Base); } protected: diff --git a/Source/Ember/Variations02.h b/Source/Ember/Variations02.h index 5a006e4..58c3e86 100644 --- a/Source/Ember/Variations02.h +++ b/Source/Ember/Variations02.h @@ -692,8 +692,9 @@ public: virtual void Precalc() override { - m_V = m_Weight * m_BlurPixelizeSize; - m_InvSize = 1 / m_BlurPixelizeSize; + auto zsize = Zeps(m_BlurPixelizeSize); + m_V = m_Weight * zsize; + m_InvSize = 1 / zsize; } protected: @@ -841,7 +842,7 @@ protected: 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_S, prefix + "crop_scatter_area", 0, eParamType::REAL)); 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_")); @@ -882,9 +883,6 @@ public: 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)); @@ -899,11 +897,10 @@ public: 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; + T omega = (m_BcbwFifth * rand.Frand01()) + 1; + T temp = m_Weight * omega; + helper.Out.x = temp * std::cos(ang); + helper.Out.y = temp * std::sin(ang); } else { @@ -925,30 +922,28 @@ public: 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; + string bcbwfifth = "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 weight = " << weight << ";\n" + << "\t\treal_t scale = " << scale << ";\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 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 real_t omega = fma(" << bcbwfifth << ", MwcNext01(mwc), (real_t)(1.0));\n" + << "\t\t real_t temp = weight * omega;\n" + << "\t\t vOut.x = temp * cos(ang);\n" + << "\t\t vOut.y = temp * sin(ang);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" @@ -965,6 +960,7 @@ public: virtual void Precalc() override { m_Bcbw = std::abs(m_BorderWidth); + m_BcbwFifth = T(0.2) * m_Bcbw; } protected: @@ -975,12 +971,14 @@ protected: 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. + m_Params.push_back(ParamWithName(true, &m_BcbwFifth, prefix + "bcircle_bcbw_fifth"));//Precalc. } private: T m_Scale; T m_BorderWidth; T m_Bcbw;//Precalc. + T m_BcbwFifth; }; /// @@ -2584,38 +2582,60 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T d, r = helper.m_PrecalcSqrtSumSquares; - - if (r > 1) + if (Compat::m_Compat) { - if (rand.Frand01() > T(0.5)) + T d, r = helper.m_PrecalcSqrtSumSquares; + + if (r > 1) { - d = std::sqrt(r + helper.In.x); - helper.Out.x = m_V2 * d; - helper.Out.y = -(m_V2 / d * helper.In.y); + 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 { - 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; + 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; + } } } else { - if (rand.Frand01() > T(0.5)) + T r2 = helper.m_PrecalcSumSquares; + T sr = helper.m_PrecalcSqrtSumSquares; + T aux = r2 > 1 ? T(1) : T(-1); + T temp = std::sqrt(sr + helper.In.x); + + 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); + helper.Out.x = m_V2 * aux * temp; + helper.Out.y = m_V2 * (-helper.In.y / Zeps(temp)); } 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; + T tempweight = m_V2 / Zeps(sr); + helper.Out.x = tempweight * aux * temp; + helper.Out.y = tempweight * (helper.In.y / Zeps(temp)); } } @@ -2630,42 +2650,67 @@ public: 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" + + if (Compat::m_Compat) + { + 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"; + } + else + { + ss << "\t{\n" + << "\t\treal_t r2 = precalcSumSquares;\n" + << "\t\treal_t sr = precalcSqrtSumSquares;\n" + << "\t\treal_t aux = r2 > 1 ? (real_t)(1.0) : (real_t)(-1.0);\n" + << "\t\treal_t temp = sqrt(sr + vIn.x);\n" + << "\n" + << "\t\tif (MwcNext01(mwc) < (real_t)(0.5))\n" + << "\t\t{\n" + << "\t\t vOut.x = " << v2 << " * aux * temp;\n" + << "\t\t vOut.y = " << v2 << " * (-vIn.y / Zeps(temp));\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t real_t tempweight = " << v2 << " / Zeps(sr);\n" + << "\t\t vOut.x = tempweight * aux * temp;\n" + << "\t\t vOut.y = tempweight * (vIn.y / Zeps(temp));\n" + << "\t\t}\n"; + } + + ss << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -2673,7 +2718,7 @@ public: virtual void Precalc() override { - m_V2 = m_Weight * std::sqrt(T(2)) / 2; + m_V2 = m_Weight * (std::sqrt(T(2)) / 2); } virtual vector OpenCLGlobalFuncNames() const override @@ -3109,9 +3154,9 @@ protected: { 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(&m_P, prefix + "hypertile_p", 3)); + m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile_q", 7)); + m_Params.push_back(ParamWithName(&m_N, prefix + "hypertile_n", 0)); m_Params.push_back(ParamWithName(true, &m_Real, prefix + "hypertile_real"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Imag, prefix + "hypertile_imag")); } @@ -3140,7 +3185,13 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T temp = rand.Crand() * m_Pa; + T temp; + + if (Compat::m_Compat) + temp = rand.Crand() * m_Pa; + else + temp = Floor(rand.Frand01() * m_IP) * m_Pa; + T sina = std::sin(temp); T cosa = std::cos(temp); T re = m_R * cosa; @@ -3149,7 +3200,7 @@ public: 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)); + T vr = m_Weight / Zeps(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); @@ -3167,17 +3218,23 @@ public: 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 = MwcNextCrand(mwc) * " << pa << ";\n" - << "\t\treal_t sina = sin(temp);\n" + ss << "\t{\n"; + + if (Compat::m_Compat) + ss << "\t\treal_t temp = MwcNextCrand(mwc) * " << pa << ";\n"; + else + ss << "\t\treal_t temp = floor(MwcNext01(mwc) * " << ip << ") * " << pa << ";\n"; + + ss << "\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 r = " << r << ";\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" + << "\t\treal_t vr = " << weight << " / Zeps(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" @@ -3195,13 +3252,18 @@ public: m_IP = T((int)m_P); } + 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 + "hypertile1_p", T(3))); - m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile1_q", T(7))); + m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile1_p", 3)); + m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile1_q", 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")); @@ -3237,7 +3299,7 @@ public: 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 vr = m_Weight / Zeps(SQR(c) + SQR(d)); T temp = rand.Crand() * m_Pa; T sina = std::sin(temp); T cosa = std::cos(temp); @@ -3258,13 +3320,14 @@ public: 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 r = " << r << ";\n" + << "\t\treal_t a = vIn.x + r;\n" << "\t\treal_t b = vIn.y;\n" - << "\t\treal_t c = fma(" << r << ", vIn.x, (real_t)(1.0));\n" - << "\t\treal_t d = " << r << " * vIn.y;\n" + << "\t\treal_t c = fma(r, vIn.x, (real_t)(1.0));\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 vr = " << weight << " / Zeps(fma(c, c, SQR(d)));\n" << "\t\treal_t temp = MwcNextCrand(mwc) * " << pa << ";\n" << "\t\treal_t sina = sin(temp);\n" << "\t\treal_t cosa = cos(temp);\n" @@ -3284,13 +3347,18 @@ public: m_R = (r2 > 0) ? T(1) / sqrt(r2) : T(1); } + 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 + "hypertile2_p", T(3))); - m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile2_q", T(7))); + m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile2_p", 3)); + m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile2_q", 7)); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile2_pa"));//Precalc. m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile2_r")); } @@ -3717,14 +3785,23 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { + T a; 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(size_t(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; + + if (Compat::m_Compat)//You need to implement this on the gpu and make sure this is even what the original does. Also search all julias that use "root". + { + a = (std::atan2(y, x) + M_2PI * rand.Rand(size_t(m_AbsN))) / m_Power; + } + else + { + auto root = (int)(m_AbsN * rand.Frand01()); + a = (std::atan2(y, x) + root * M_2PI) / m_Power; + } + + helper.Out.x = r * std::cos(a); + helper.Out.y = r * std::sin(a); helper.Out.z = DefaultZ(helper); } @@ -3746,15 +3823,19 @@ public: string absn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t a;\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\treal_t r = " << weight << " * pow(fma(x, x, SQR(y)), " << cn << ");\n"; + + if (Compat::m_Compat) + ss << "\t\ta = fma(M_2PI, (real_t)MwcNextRange(mwc, (uint)" << absn << "), atan2(y, x)) / " << power << ";\n"; + else + ss << "\t\tint root = (int)(" << absn << " * MwcNext01(mwc));\n" + << "\t\ta = (atan2(y, x) + root + M_2PI) / " << power << ";\n"; + + ss << "\t\tvOut.x = r * cos(a);\n" + << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -3765,7 +3846,11 @@ public: if (m_Power == 0) m_Power = 2; - m_AbsN = T(int(abs(m_Power))); + if (Compat::m_Compat) + m_AbsN = T(int(abs(m_Power))); + else + m_AbsN = std::abs(m_Power); + m_Cn = m_Dist / m_Power / 2; } @@ -3780,7 +3865,7 @@ protected: 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_Power, prefix + "julian2_power", 2, eParamType::REAL_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")); @@ -3851,9 +3936,10 @@ public: 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; + auto p = Zeps(m_Power); + m_HalfInvPower = T(0.5) * (m_Divisor / p); + m_InvPower = m_Divisor / p; + m_InvPower2pi = M_2PI / p; } protected: @@ -3861,8 +3947,8 @@ protected: { 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(&m_Power, prefix + "juliaq_power", 3, eParamType::REAL_NONZERO)); + m_Params.push_back(ParamWithName(&m_Divisor, prefix + "juliaq_divisor", 2, eParamType::REAL_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")); @@ -3949,7 +4035,7 @@ protected: 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(&m_Power, prefix + "murl_power", 2, eParamType::REAL, 2)); 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")); @@ -4052,7 +4138,7 @@ protected: 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(&m_Power, prefix + "murl2_power", 1)); 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")); @@ -4075,7 +4161,7 @@ template class NPolarVariation : public ParametricVariation { public: - NPolarVariation(T weight = 1.0) : ParametricVariation("npolar", eVariationId::VAR_NPOLAR, weight, true, false, false, true, false) + NPolarVariation(T weight = 1.0) : ParametricVariation("npolar", eVariationId::VAR_NPOLAR, weight, true, false, false, true, true) { Init(); } @@ -4086,23 +4172,47 @@ public: { T x, y; - if (m_IsOdd != 0) + if (Compat::m_Compat) { - T angle = (std::atan2(helper.In.y, helper.In.x) + M_2PI * rand.Rand(size_t(m_AbsN))) * m_Nnz; - T r = m_Weight * std::pow(SQR(helper.In.x) + SQR(helper.In.y), m_Cn) * m_Parity; - x = std::cos(angle) * r; - y = std::sin(angle) * r; + if (m_IsOdd != 0) + { + T angle = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(size_t(m_AbsN))) / m_Nnz; + T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn) * m_Parity; + x = std::cos(angle) * r; + y = std::sin(angle) * r; + } + else + { + x = m_Vvar * helper.m_PrecalcAtanxy; + y = m_Vvar2 * std::log(helper.m_PrecalcSumSquares); + T angle = (std::atan2(y, x) + M_2PI * rand.Rand(size_t(m_AbsN))) / m_Nnz; + T r = m_Weight * std::pow(SQR(x) + SQR(y), m_Cn); + T sina = std::sin(angle) * r; + T cosa = std::cos(angle) * r; + x = m_Vvar2 * std::log(SQR(cosa) + SQR(sina)); + y = m_Vvar * std::atan2(cosa, sina); + } } else { - x = m_Vvar * helper.m_PrecalcAtanxy; - y = m_Vvar2 * std::log(helper.m_PrecalcSumSquares); - T angle = (std::atan2(y, x) + M_2PI * rand.Rand(size_t(m_AbsN))) * m_Nnz; - T r = m_Weight * std::pow(SQR(x) + SQR(y), m_Cn); - T sina = std::sin(angle) * r; - T cosa = std::cos(angle) * r; - x = m_Vvar2 * std::log(SQR(cosa) + SQR(sina)); - y = m_Vvar * std::atan2(cosa, sina); + if (m_IsOdd != 0) + { + T angle = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(size_t(m_AbsN))) / m_Nnz; + T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); + x = std::cos(angle) * r; + y = std::sin(angle) * r; + } + else + { + x = m_Vvar * helper.m_PrecalcAtanxy; + y = m_Vvar2 * std::log(helper.m_PrecalcSumSquares); + T angle = (std::atan2(y, x) + M_2PI * rand.Rand(size_t(m_AbsN))) / m_Nnz; + T r = m_Weight * std::pow(SQR(x) + SQR(y), m_Cn) * m_Parity; + T sina = std::sin(angle) * r; + T cosa = std::cos(angle) * r; + x = m_Vvar2 * 2 * std::log(r); + y = m_Vvar * std::atan2(cosa, sina); + } } helper.Out.x = x; @@ -4127,41 +4237,69 @@ public: string isOdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x, y;\n" - << "\n" - << "\t\tif (" << isOdd << " != 0)\n" - << "\t\t{\n" - << "\t\t real_t angle = (atan2(vIn.y, vIn.x) + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) * " << nnz << ";\n" - << "\t\t real_t r = " << weight << " * pow(SQR(vIn.x) + SQR(vIn.y), " << cn << ") * " << parity << ";\n" - << "\t\t x = cos(angle) * r;\n" - << "\t\t y = sin(angle) * r;\n" - << "\t\t}\n" - << "\t\telse\n" - << "\t\t{\n" - << "\t\t x = " << vvar << " * precalcAtanxy;\n" - << "\t\t y = " << vvar2 << " * log(precalcSumSquares);\n" - << "\t\t real_t angle = (atan2(y, x) + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) * " << nnz << ";\n" - << "\t\t real_t r = " << weight << " * pow(SQR(x) + SQR(y), " << cn << ");\n" - << "\t\t real_t sina = sin(angle) * r;\n" - << "\t\t real_t cosa = cos(angle) * r;\n" - << "\t\t x = " << vvar2 << " * log(SQR(cosa) + SQR(sina));\n" - << "\t\t y = " << vvar << " * atan2(cosa, sina);\n" - << "\t\t}\n" - << "\n" - << "\t\tvOut.x = x;\n" - << "\t\tvOut.y = y;\n" - << "\t\tvOut.z = " << DefaultZCl() - << "\t}\n"; + << "\t\treal_t vvar = " << vvar << ";\n" + << "\t\treal_t vvar2 = " << vvar2 << ";\n" + << "\n"; + + if (Compat::m_Compat) + { + ss << "\t\tif (" << isOdd << " != 0)\n" + << "\t\t{\n" + << "\t\t real_t angle = (precalcAtanyx + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << nnz << ";\n" + << "\t\t real_t r = " << weight << " * pow(precalcSumSquares, " << cn << ") * " << parity << ";\n" + << "\t\t x = cos(angle) * r;\n" + << "\t\t y = sin(angle) * r;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t x = vvar * precalcAtanxy;\n" + << "\t\t y = vvar2 * log(precalcSumSquares);\n" + << "\t\t real_t angle = (atan2(y, x) + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << nnz << ";\n" + << "\t\t real_t r = " << weight << " * pow(SQR(x) + SQR(y), " << cn << ");\n" + << "\t\t real_t sina = sin(angle) * r;\n" + << "\t\t real_t cosa = cos(angle) * r;\n" + << "\t\t x = vvar2 * log(SQR(cosa) + SQR(sina));\n" + << "\t\t y = vvar * atan2(cosa, sina);\n" + << "\t\t}\n"; + } + else + { + ss << "\t\tif (" << isOdd << " != 0)\n" + << "\t\t{\n" + << "\t\t real_t angle = (precalcAtanyx + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << nnz << ";\n" + << "\t\t real_t r = " << weight << " * pow(precalcSumSquares, " << cn << ");\n" + << "\t\t x = cos(angle) * r;\n" + << "\t\t y = sin(angle) * r;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t x = vvar * precalcAtanxy;\n" + << "\t\t y = vvar2 * log(precalcSumSquares);\n" + << "\t\t real_t angle = (atan2(y, x) + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << nnz << ";\n" + << "\t\t real_t r = " << weight << " * pow(SQR(x) + SQR(y), " << cn << ") * " << parity << ";\n" + << "\t\t real_t sina = sin(angle) * r;\n" + << "\t\t real_t cosa = cos(angle) * r;\n" + << "\t\t x = vvar2 * (real_t)(2.0) * log(r);\n" + << "\t\t y = vvar * atan2(cosa, sina);\n" + << "\t\t}\n"; + } + + ss << "\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 = 1 / ((m_N == 0) ? 1 : m_N); + 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_AbsN = std::abs(m_Nnz); m_Cn = 1 / m_Nnz / 2; - m_IsOdd = T(abs(int(m_Parity)) & 1); + m_IsOdd = std::fmod(std::abs(m_Parity), T(2.0)); } protected: @@ -4169,8 +4307,8 @@ protected: { 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(&m_Parity, prefix + "npolar_parity", 0)); + m_Params.push_back(ParamWithName(&m_N, prefix + "npolar_n", 1)); 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")); @@ -5487,12 +5625,14 @@ public: string weight = WeightDefineString(); string vvar2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. ss << "\t{\n" + << "\t\treal_t vvar2 = " << vvar2 << ";\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" + << "\t\treal_t vvar2r = vvar2 * r;\n" << "\n" - << "\t\tvOut.x = " << vvar2 << " * r * s;\n" - << "\t\tvOut.y = " << vvar2 << " * r * c;\n" + << "\t\tvOut.x = vvar2r * s;\n" + << "\t\tvOut.y = vvar2r * c;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -5601,7 +5741,7 @@ protected: 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(&m_Power, prefix + "wavesn_power", 1)); m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "wavesn_absn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "wavesn_cn")); } @@ -6034,14 +6174,15 @@ public: virtual void Precalc() override { + auto spread = Zeps(m_Spread); 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); + m_InvSpread = T(0.5) / spread; + m_FullSpread = M_2PI * spread; + m_SpreadUint = uint(spread); } protected: @@ -6051,8 +6192,8 @@ protected: 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(&m_Divisor, prefix + "cpow2_divisor", 1)); + m_Params.push_back(ParamWithName(&m_Spread, prefix + "cpow2_spread", 1)); 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")); diff --git a/Source/Ember/Variations03.h b/Source/Ember/Variations03.h index a503c1c..1991ffb 100644 --- a/Source/Ember/Variations03.h +++ b/Source/Ember/Variations03.h @@ -285,8 +285,18 @@ public: T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Zeps(T(Floor(m_Power))); T sina = std::sin(alpha); T cosa = std::cos(alpha); - helper.Out.x = m_Weight * cosa / r; - helper.Out.y = m_Weight * sina / r; + + if (Compat::m_Compat) + { + helper.Out.x = m_Weight * cosa / r; + helper.Out.y = m_Weight * sina / r; + } + else + { + helper.Out.x = m_Weight * sina / r; + helper.Out.y = m_Weight * cosa / r; + } + helper.Out.z = DefaultZ(helper); } @@ -300,15 +310,27 @@ public: string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t power = " << power << ";\n" << "\t\treal_t r = Zeps(pow(precalcSqrtSumSquares, " << dist << "));\n" - << "\t\tint n = floor(" << power << " * MwcNext01(mwc));\n" - << "\t\treal_t alpha = fma(n, M_2PI / Zeps(floor(" << power << ")), precalcAtanyx);\n" + << "\t\tint n = floor(power * MwcNext01(mwc));\n" + << "\t\treal_t alpha = fma(n, M_2PI / Zeps(floor(power)), precalcAtanyx);\n" << "\t\treal_t sina = sin(alpha);\n" << "\t\treal_t cosa = cos(alpha);\n" - << "\n" - << "\t\tvOut.x = " << weight << " * cosa / r;\n" - << "\t\tvOut.y = " << weight << " * sina / r;\n" - << "\t\tvOut.z = " << DefaultZCl() + << "\n"; + + if (Compat::m_Compat) + { + ss << "\t\tvOut.x = weight * cosa / r;\n" + << "\t\tvOut.y = weight * sina / r;\n"; + } + else + { + ss << "\t\tvOut.x = weight * sina / r;\n" + << "\t\tvOut.y = weight * cosa / r;\n"; + } + + ss << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } @@ -1214,7 +1236,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Power, prefix + "starblur_power", 5, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_Power, prefix + "starblur_power", 5)); m_Params.push_back(ParamWithName(&m_Range, prefix + "starblur_range", T(0.4016228317))); m_Params.push_back(ParamWithName(true, &m_Length, prefix + "starblur_length"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "starblur_alpha")); @@ -1382,42 +1404,77 @@ private: /// /// CropN. +/// By zy0rg. /// template class CropNVariation : public ParametricVariation { public: + using Variation::m_NeedPrecalcSumSquares; + using Variation::m_NeedPrecalcAngles; CropNVariation(T weight = 1.0) : ParametricVariation("cropn", eVariationId::VAR_CROPN, weight, true, true, true, false, true) { Init(); + m_NeedPrecalcSumSquares = !Compat::m_Compat; + m_NeedPrecalcAngles = Compat::m_Compat; } PARVARCOPY(CropNVariation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T xang = (helper.m_PrecalcAtanyx + T(M_PI)) / m_Alpha; - xang = (xang - int(xang)) * m_Alpha; - xang = std::cos((xang < m_Alpha / 2) ? xang : m_Alpha - xang); - T xr = xang > 0 ? m_Radius / xang : 1; - - if ((helper.m_PrecalcSqrtSumSquares > xr) == (m_Power > 0)) + if (Compat::m_Compat) { - if (m_Zero == 1) + T xang = (helper.m_PrecalcAtanyx + T(M_PI)) / m_Alpha; + xang = (xang - int(xang)) * m_Alpha; + xang = std::cos((xang < m_AlphaDiv2) ? xang : m_Alpha - xang); + T xr = xang > 0 ? m_Radius / xang : 1; + + if ((helper.m_PrecalcSqrtSumSquares > xr) == (m_Power > 0)) { - helper.Out.x = helper.Out.y = 0; + if (m_Zero == 1) + { + helper.Out.x = helper.Out.y = 0; + } + else + { + T rdc = xr + (rand.Frand01() * T(0.5) * m_ScatterDist); + helper.Out.x = m_Weight * rdc * helper.m_PrecalcCosa; + helper.Out.y = m_Weight * rdc * helper.m_PrecalcSina; + } } else { - T rdc = xr + (rand.Frand01() * T(0.5) * m_ScatterDist); - helper.Out.x = m_Weight * rdc * helper.m_PrecalcCosa; - helper.Out.y = m_Weight * rdc * helper.m_PrecalcSina; + helper.Out.x = m_Weight * helper.In.x; + 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; + T r2 = helper.m_PrecalcSumSquares; + T aModAlpha = std::fmod(helper.m_PrecalcAtanyx + T(M_PI), m_Alpha); + T xang = std::cos(aModAlpha < m_AlphaDiv2 ? aModAlpha : m_Alpha - aModAlpha); + T xr = xang > 0 ? m_Radius / Zeps(xang) : T(1); + T xr2 = xr * xr; + + if ((r2 > xr2) == (m_Power > 0)) + { + if (m_Zero == 0) + { + helper.Out.x = helper.Out.y = 0; + } + else + { + T temp = (xr + rand.Frand01() * m_ScatterDist) * m_Weight / Zeps(std::sqrt(r2)); + helper.Out.x = temp * helper.In.x; + helper.Out.y = temp * helper.In.y; + } + } + else + { + helper.Out.x = m_Weight * helper.In.x; + helper.Out.y = m_Weight * helper.In.y; + } } helper.Out.z = DefaultZ(helper); @@ -1436,45 +1493,103 @@ public: string zero = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string workPower = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string alpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string alphaDiv2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t xang = (precalcAtanyx + MPI) / " << alpha << ";\n" - << "\n" - << "\t\txang = (xang - (int) xang) * " << alpha << ";\n" - << "\t\txang = cos((xang < " << alpha << " / 2) ? xang : " << alpha << " - xang);\n" - << "\n" - << "\t\treal_t xr = xang > 0 ? " << radius << " / xang : 1;\n" - << "\n" - << "\t\tif ((precalcSqrtSumSquares > xr) == (" << power << " > 0))\n" - << "\t\t{\n" - << "\t\t if (" << zero << " == 1)\n" - << "\t\t {\n" - << "\t\t vOut.x = vOut.y = 0;\n" - << "\t\t }\n" - << "\t\t else\n" - << "\t\t {\n" - << "\t\t real_t rdc = fma(MwcNext01(mwc), (real_t)(0.5) * " << scatterDist << ", xr);\n" - << "\n" - << "\t\t vOut.x = " << weight << " * rdc * precalcCosa;\n" - << "\t\t vOut.y = " << weight << " * rdc * precalcSina;\n" - << "\t\t }\n" - << "\t\t}\n" - << "\t\telse\n" - << "\t\t{\n" - << "\t\t vOut.x = " << weight << " * vIn.x;\n" - << "\t\t vOut.y = " << weight << " * vIn.y;\n" - << "\t\t}\n" - << "\n" - << "\t\tvOut.z = " << DefaultZCl() - << "\t}\n"; + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t alpha = " << alpha << ";\n"; + + if (Compat::m_Compat) + { + ss << "\t\treal_t xang = (precalcAtanyx + MPI) / alpha;\n" + << "\n" + << "\t\txang = (xang - (int) xang) * alpha;\n" + << "\t\txang = cos((xang < " << alphaDiv2 << ") ? xang : alpha - xang);\n" + << "\n" + << "\t\treal_t xr = xang > 0 ? " << radius << " / xang : 1;\n" + << "\n" + << "\t\tif ((precalcSqrtSumSquares > xr) == (" << power << " > 0))\n" + << "\t\t{\n" + << "\t\t if (" << zero << " == 1)\n" + << "\t\t {\n" + << "\t\t vOut.x = vOut.y = 0;\n" + << "\t\t }\n" + << "\t\t else\n" + << "\t\t {\n" + << "\t\t real_t rdc = fma(MwcNext01(mwc), (real_t)(0.5) * " << scatterDist << ", xr);\n" + << "\n" + << "\t\t vOut.x = weight * rdc * precalcCosa;\n" + << "\t\t vOut.y = weight * rdc * precalcSina;\n" + << "\t\t }\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t vOut.x = weight * vIn.x;\n" + << "\t\t vOut.y = weight * vIn.y;\n" + << "\t\t}\n" + << "\n" + << "\t\tvOut.z = " << DefaultZCl() + << "\t}\n"; + } + else + { + ss << "\t\treal_t r2 = precalcSumSquares;\n" + << "\t\treal_t aModAlpha = fmod(precalcAtanyx + MPI, alpha);\n" + << "\t\treal_t xang = cos(aModAlpha < " << alphaDiv2 << " ? aModAlpha : alpha - aModAlpha);\n" + << "\t\treal_t xr = xang > 0 ? " << radius << " / Zeps(xang) : (real_t)1.0;\n" + << "\t\treal_t xr2 = xr * xr;\n" + << "\n" + << "\t\tif ((r2 > xr2) == (" << power << " > 0))\n" + << "\t\t{\n" + << "\t\t if (" << zero << " == 0)\n" + << "\t\t {\n" + << "\t\t vOut.x = vOut.y = 0;\n" + << "\t\t }\n" + << "\t\t else\n" + << "\t\t {\n" + << "\t\t real_t temp = fma(MwcNext01(mwc), " << scatterDist << ", xr) * weight / Zeps(sqrt(r2));\n" + << "\n" + << "\t\t vOut.x = temp * vIn.x;\n" + << "\t\t vOut.y = temp * vIn.y;\n" + << "\t\t }\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t vOut.x = weight * vIn.x;\n" + << "\t\t vOut.y = weight * vIn.y;\n" + << "\t\t}\n" + << "\n" + << "\t\tvOut.z = " << DefaultZCl() + << "\t}\n"; + } + return ss.str(); } + virtual vector OpenCLGlobalFuncNames() const override + { + if (Compat::m_Compat) + return vector { }; + else + return vector { "Zeps" }; + } + virtual void Precalc() override { - bool mode = m_Power > 0; - m_WorkPower = mode ? m_Power : -m_Power; - ClampGteRef(m_WorkPower, 2); - m_Alpha = M_2PI / m_WorkPower; + if (Compat::m_Compat) + { + bool mode = m_Power > 0; + m_WorkPower = mode ? m_Power : -m_Power; + ClampGteRef(m_WorkPower, 2); + m_Alpha = M_2PI / m_WorkPower; + } + else + { + m_Alpha = M_2PI / std::max(T(2), std::abs(m_Power)); + } + + m_AlphaDiv2 = m_Alpha / 2; + m_NeedPrecalcSumSquares = !Compat::m_Compat; + m_NeedPrecalcAngles = Compat::m_Compat; } protected: @@ -1482,12 +1597,13 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Power, prefix + "cropn_power", -5)); + m_Params.push_back(ParamWithName(&m_Power, prefix + "cropn_power", 5)); m_Params.push_back(ParamWithName(&m_Radius, prefix + "cropn_radius", 1)); m_Params.push_back(ParamWithName(&m_ScatterDist, prefix + "cropn_scatterdist")); - m_Params.push_back(ParamWithName(&m_Zero, prefix + "cropn_zero", 0, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Zero, prefix + "cropn_zero")); m_Params.push_back(ParamWithName(true, &m_WorkPower, prefix + "cropn_workpower"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "cropn_alpha")); + m_Params.push_back(ParamWithName(true, &m_AlphaDiv2, prefix + "cropn_alpha_div_2")); } private: @@ -1497,6 +1613,7 @@ private: T m_Zero; T m_WorkPower;//Precalc. T m_Alpha; + T m_AlphaDiv2; }; /// @@ -1655,13 +1772,13 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Mode, prefix + "blob2_mode", 0, eParamType::INTEGER, -1, 1)); - m_Params.push_back(ParamWithName(&m_N, prefix + "blob2_n", 5, eParamType::INTEGER)); + m_Params.push_back(ParamWithName(&m_Mode, prefix + "blob2_mode", T(0.5))); + m_Params.push_back(ParamWithName(&m_N, prefix + "blob2_n", 1)); m_Params.push_back(ParamWithName(&m_Radius, prefix + "blob2_radius")); m_Params.push_back(ParamWithName(&m_Prescale, prefix + "blob2_prescale", 1)); m_Params.push_back(ParamWithName(&m_Postscale, prefix + "blob2_postscale", T(0.5))); m_Params.push_back(ParamWithName(&m_Symmetry, prefix + "blob2_symmetry", 0, eParamType::REAL, -1, 1)); - m_Params.push_back(ParamWithName(&m_Compensation, prefix + "blob2_compensation", 0, eParamType::REAL, 0, 1)); + m_Params.push_back(ParamWithName(&m_Compensation, prefix + "blob2_compensation", 0)); m_Params.push_back(ParamWithName(true, &m_DeltaHelp, prefix + "blob2_deltahelp"));//Precalc. } @@ -2688,11 +2805,24 @@ public: { T preX = helper.In.x * (m_XDistort + 1); T preY = helper.In.y * (m_YDistort + 1); - T temp = std::atan2(preY, preX) * m_InvN + rand.Crand() * m_Inv2PiN; - T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); - helper.Out.x = r * std::cos(temp); - helper.Out.y = r * std::sin(temp); - helper.Out.z = DefaultZ(helper); + + if (Compat::m_Compat) + { + T temp = std::atan2(preY, preX) * m_InvN + rand.Crand() * m_Inv2PiN; + T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); + helper.Out.x = r * std::cos(temp); + helper.Out.y = r * std::sin(temp); + helper.Out.z = m_Weight * helper.In.z; + } + else + { + int root = (int)(rand.Frand01() * m_Power); + T a = std::atan2(preY, preX) * m_InvN + root * m_Inv2PiN; + T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn); + helper.Out.x = r * std::cos(a); + helper.Out.y = r * std::sin(a); + helper.Out.z = DefaultZ(helper); + } } virtual string OpenCLString() const override @@ -2710,15 +2840,32 @@ public: string invN = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string inv2PiN = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t weight = " << weight << ";\n" << "\t\treal_t preX = vIn.x * (" << xDistort << " + 1);\n" - << "\t\treal_t preY = vIn.y * (" << yDistort << " + 1);\n" - << "\t\treal_t temp = fma(atan2(preY, preX), " << invN << ", MwcNextCrand(mwc) * " << inv2PiN << ");\n" - << "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cN << ");\n" - << "\n" - << "\t\tvOut.x = r * cos(temp);\n" - << "\t\tvOut.y = r * sin(temp);\n" - << "\t\tvOut.z = " << DefaultZCl() - << "\t}\n"; + << "\t\treal_t preY = vIn.y * (" << yDistort << " + 1);\n"; + + if (Compat::m_Compat) + { + ss << "\t\treal_t temp = fma(atan2(preY, preX), " << invN << ", MwcNextCrand(mwc) * " << inv2PiN << ");\n" + << "\t\treal_t r = weight * pow(precalcSumSquares, " << cN << ");\n" + << "\n" + << "\t\tvOut.x = r * cos(temp);\n" + << "\t\tvOut.y = r * sin(temp);\n" + << "\t\tvOut.z = weight * vIn.z;\n" + << "\t}\n"; + } + else + { + ss << "\t\tint root = (int)(MwcNext01(mwc) * " << power << ");\n" + << "\t\treal_t temp = fma(atan2(preY, preX), " << invN << ", root * " << inv2PiN << ");\n" + << "\t\treal_t r = weight * pow(precalcSumSquares, " << cN << ");\n" + << "\n" + << "\t\tvOut.x = r * cos(temp);\n" + << "\t\tvOut.y = r * sin(temp);\n" + << "\t\tvOut.z = weight * vIn.z;\n" + << "\t}\n"; + } + return ss.str(); } @@ -2727,7 +2874,7 @@ public: auto zp = Zeps(m_Power); m_InvN = m_Dist / zp; m_Inv2PiN = M_2PI / zp; - m_Cn = m_Dist / zp / 2; + m_Cn = m_InvN / 2; } protected: @@ -3727,8 +3874,8 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_A, prefix + "collideoscope_a", 0, eParamType::REAL_CYCLIC, 0, 1)); - m_Params.push_back(ParamWithName(&m_Num, prefix + "collideoscope_num", 1, eParamType::INTEGER)); + m_Params.push_back(ParamWithName(&m_A, prefix + "collideoscope_a")); + m_Params.push_back(ParamWithName(&m_Num, prefix + "collideoscope_num", 1)); m_Params.push_back(ParamWithName(true, &m_Ka, prefix + "collideoscope_ka"));//Precalc. m_Params.push_back(ParamWithName(true, &m_KnPi, prefix + "collideoscope_kn_pi")); m_Params.push_back(ParamWithName(true, &m_KaKn, prefix + "collideoscope_ka_kn")); @@ -3972,7 +4119,7 @@ protected: string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Rotate, prefix + "bTransform_rotate")); - m_Params.push_back(ParamWithName(&m_Power, prefix + "bTransform_power", 1, eParamType::INTEGER, 1, T(INT_MAX))); + m_Params.push_back(ParamWithName(&m_Power, prefix + "bTransform_power", 0, eParamType::REAL_NONZERO, 1, T(INT_MAX))); m_Params.push_back(ParamWithName(&m_Move, prefix + "bTransform_move")); m_Params.push_back(ParamWithName(&m_Split, prefix + "bTransform_split")); } @@ -4060,9 +4207,9 @@ public: virtual void Precalc() override { m_CnPi = m_Num * T(M_1_PI); - m_PiCn = T(M_PI) / m_Num; + m_PiCn = T(M_PI) / Zeps(m_Num); m_Ca = T(M_PI) * m_A; - m_CaCn = m_Ca / m_Num; + m_CaCn = m_Ca / Zeps(m_Num); } protected: @@ -4070,8 +4217,8 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_A, prefix + "bCollide_a", 0, eParamType::REAL_CYCLIC, 0, 1)); - m_Params.push_back(ParamWithName(&m_Num, prefix + "bCollide_num", 1, eParamType::INTEGER, 1, T(INT_MAX))); + m_Params.push_back(ParamWithName(&m_A, prefix + "bCollide_a", 0, eParamType::REAL_CYCLIC, -1, 1)); + m_Params.push_back(ParamWithName(&m_Num, prefix + "bCollide_num", 1, eParamType::REAL, EPS, T(INT_MAX))); m_Params.push_back(ParamWithName(true, &m_Ca, prefix + "bCollide_ca"));//Precalc. m_Params.push_back(ParamWithName(true, &m_CnPi, prefix + "bCollide_cn_pi")); m_Params.push_back(ParamWithName(true, &m_CaCn, prefix + "bCollide_ca_cn")); @@ -4498,7 +4645,7 @@ public: } else { - r2 = 1 / r2; + r2 = 1 / Zeps(r2); x = helper.In.x * r2; } @@ -4537,7 +4684,7 @@ public: << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" - << "\t\t r2 = 1 / r2;\n" + << "\t\t r2 = 1 / Zeps(r2);\n" << "\t\t x = vIn.x * r2;\n" << "\t\t}\n" << "\n" @@ -4566,7 +4713,7 @@ public: virtual vector OpenCLGlobalFuncNames() const override { - return vector { "SafeSqrt" }; + return vector { "SafeSqrt", "Zeps" }; } virtual void Precalc() override @@ -4912,7 +5059,7 @@ public: nu = fmod(nu + m_Rotate + T(M_PI), M_2PI) - T(M_PI); helper.Out.x = m_Weight * xmax * std::cos(nu); - helper.Out.y = m_Weight * std::sqrt(xmax - 1) * std::sqrt(xmax + 1) * std::sin(nu); + helper.Out.y = m_Weight * std::sqrt(xmax * xmax - 1) * std::sin(nu); helper.Out.z = DefaultZ(helper); } @@ -4925,6 +5072,7 @@ public: string weight = WeightDefineString(); string rotate = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t weight = " << weight << ";\n" << "\t\treal_t tmp = precalcSumSquares + 1;\n" << "\t\treal_t tmp2 = 2 * vIn.x;\n" << "\t\treal_t xmax = (SafeSqrt(tmp + tmp2) + SafeSqrt(tmp - tmp2)) * (real_t)(0.5);\n" @@ -4939,8 +5087,8 @@ public: << "\n" << "\t\tnu = fmod(nu + " << rotate << " + MPI, M_2PI) - MPI;\n" << "\n" - << "\t\tvOut.x = " << weight << " * xmax * cos(nu);\n" - << "\t\tvOut.y = " << weight << " * sqrt(xmax - 1) * sqrt(xmax + 1) * sin(nu);\n" + << "\t\tvOut.x = weight * xmax * cos(nu);\n" + << "\t\tvOut.y = weight * sqrt(xmax * xmax - 1) * sin(nu);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); diff --git a/Source/Ember/Variations04.h b/Source/Ember/Variations04.h index dc77e7c..801483e 100644 --- a/Source/Ember/Variations04.h +++ b/Source/Ember/Variations04.h @@ -304,10 +304,10 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_N, prefix + "lazyjess_n", 4, eParamType::INTEGER_NONZERO, 2)); - m_Params.push_back(ParamWithName(&m_Spin, prefix + "lazyjess_spin", T(M_PI), eParamType::REAL_CYCLIC, 0, M_2PI)); + m_Params.push_back(ParamWithName(&m_N, prefix + "lazyjess_n", 4, eParamType::REAL_NONZERO, 2)); + m_Params.push_back(ParamWithName(&m_Spin, prefix + "lazyjess_spin", T(M_PI))); m_Params.push_back(ParamWithName(&m_Space, prefix + "lazyjess_space")); - m_Params.push_back(ParamWithName(&m_Corner, prefix + "lazyjess_corner", 1, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_Corner, prefix + "lazyjess_corner", 1)); m_Params.push_back(ParamWithName(true, &m_Vertex, prefix + "lazyjess_vertex"));//Precalc. m_Params.push_back(ParamWithName(true, &m_SinVertex, prefix + "lazyjess_sin_vertex")); m_Params.push_back(ParamWithName(true, &m_PieSlice, prefix + "lazyjess_pie_slice")); @@ -742,7 +742,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Power, prefix + "squish_power", 2, eParamType::INTEGER, 2, T(INT_MAX))); + m_Params.push_back(ParamWithName(&m_Power, prefix + "squish_power", 2, eParamType::REAL_NONZERO, 2)); m_Params.push_back(ParamWithName(true, &m_InvPower, prefix + "squish_inv_power"));//Precalc. } @@ -1800,7 +1800,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Slices, prefix + "waffle_slices", 6, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_Slices, prefix + "waffle_slices", 6, eParamType::REAL_NONZERO)); m_Params.push_back(ParamWithName(&m_XThickness, prefix + "waffle_xthickness", T(0.5))); m_Params.push_back(ParamWithName(&m_YThickness, prefix + "waffle_ythickness", T(0.5))); m_Params.push_back(ParamWithName(&m_Rotation, prefix + "waffle_rotation")); @@ -2156,8 +2156,9 @@ public: { T xi = helper.In.x - m_X; T yi = helper.In.y - m_Y; + auto b = Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG; - if (m_VarType == eVariationType::VARTYPE_REG)//Original altered the input pointed to for reg. + if (b)//Original altered the input pointed to for reg. { helper.m_TransX -= m_X; helper.m_TransY -= m_Y; @@ -2169,31 +2170,29 @@ public: } const T rad = std::sqrt(SQR(xi) + SQR(yi)); - const T ang = std::atan2(yi, xi); const T rdc = m_Radius + (rand.Frand01() * T(0.5) * m_Ca); - const T s = std::sin(ang); - const T c = std::cos(ang); const int esc = rad > m_Radius; const int cr0 = int(m_Zero); - if (cr0 && esc) + if (esc) { - helper.Out.x = helper.Out.y = 0; + if (cr0) + { + helper.Out.x = helper.Out.y = 0; - if (m_VarType == eVariationType::VARTYPE_REG) - outPoint.m_X = outPoint.m_Y = 0; + if (b) + outPoint.m_X = outPoint.m_Y = 0; + } + else + { + const T ang = std::atan2(yi, xi); + const T s = std::sin(ang); + const T c = std::cos(ang); + helper.Out.x = m_Weight * rdc * c + m_X; + helper.Out.y = m_Weight * rdc * s + m_Y; + } } - else if (cr0 && !esc) - { - helper.Out.x = m_Weight * xi + m_X; - helper.Out.y = m_Weight * yi + m_Y; - } - else if (!cr0 && esc) - { - helper.Out.x = m_Weight * rdc * c + m_X; - helper.Out.y = m_Weight * rdc * s + m_Y; - } - else if (!cr0 && !esc) + else { helper.Out.x = m_Weight * xi + m_X; helper.Out.y = m_Weight * yi + m_Y; @@ -2213,59 +2212,57 @@ public: string scatterArea = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string zero = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ca = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + auto b = Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG; ss << "\t{\n" - << "\t\treal_t xi = vIn.x - " << x << ";\n" - << "\t\treal_t yi = vIn.y - " << y << ";\n" + << "\t\treal_t x = " << x << ";\n" + << "\t\treal_t y = " << y << ";\n" + << "\t\treal_t radius = " << radius << ";\n" + << "\t\treal_t xi = vIn.x - x;\n" + << "\t\treal_t yi = vIn.y - y;\n" + << "\t\treal_t weight = " << weight << ";\n" << "\n"; - if (m_VarType == eVariationType::VARTYPE_REG)//Original altered the input pointed to for reg. + if (b)//Original altered the input pointed to for reg. { - ss - << "\t\ttransX -= " << x << ";\n" - << "\t\ttransY -= " << y << ";\n" - << "\t\tvOut.z = " << weight << " * vIn.z;\n"; + ss << "\t\ttransX -= x;\n" + << "\t\ttransY -= y;\n" + << "\t\tvOut.z = weight * vIn.z;\n"; } else { - ss - << "\t\tvOut.z = vIn.z;\n"; + ss << "\t\tvOut.z = vIn.z;\n"; } - ss - << "\t\tconst real_t rad = sqrt(SQR(xi) + SQR(yi));\n" - << "\t\tconst real_t ang = atan2(yi, xi);\n" - << "\t\tconst real_t rdc = fma(MwcNext01(mwc) * (real_t)(0.5), " << ca << ", " << radius << ");\n" - << "\t\tconst real_t s = sin(ang);\n" - << "\t\tconst real_t c = cos(ang);\n" - << "\n" - << "\t\tconst int esc = rad > " << radius << ";\n" - << "\t\tconst int cr0 = (int)" << zero << ";\n" - << "\n" - << "\t\tif (cr0 && esc)\n" - << "\t\t{\n" - << "\t\t vOut.x = vOut.y = 0;\n"; + ss << "\t\tconst real_t rad = sqrt(SQR(xi) + SQR(yi));\n" + << "\t\tconst real_t rdc = fma(MwcNext01(mwc) * (real_t)(0.5), " << ca << ", radius);\n" + << "\t\tconst int esc = rad > radius;\n" + << "\t\tconst int cr0 = (int)" << zero << ";\n" + << "\n" + << "\t\tif (esc)\n" + << "\t\t{\n" + << "\t\t if (cr0)\n" + << "\t\t {\n" + << "\t\t vOut.x = vOut.y = 0;\n"; - if (m_VarType == eVariationType::VARTYPE_REG) - ss << "\t\t outPoint->m_X = outPoint->m_Y = 0;\n"; + if (b) + ss << "\t\t outPoint->m_X = outPoint->m_Y = 0;\n"; - ss - << "\t\t}\n" - << "\t\telse if (cr0 && !esc)\n" - << "\t\t{\n" - << "\t\t vOut.x = fma(" << weight << ", xi, " << x << ");\n" - << "\t\t vOut.y = fma(" << weight << ", yi, " << y << ");\n" - << "\t\t}\n" - << "\t\telse if (!cr0 && esc)\n" - << "\t\t{\n" - << "\t\t vOut.x = fma(" << weight << ", rdc * c, " << x << ");\n" - << "\t\t vOut.y = fma(" << weight << ", rdc * s, " << y << ");\n" - << "\t\t}\n" - << "\t\telse if (!cr0 && !esc)\n" - << "\t\t{\n" - << "\t\t vOut.x = fma(" << weight << ", xi, " << x << ");\n" - << "\t\t vOut.y = fma(" << weight << ", yi, " << y << ");\n" - << "\t\t}\n" - << "\t}\n"; + ss << "\t\t }\n" + << "\t\t else\n" + << "\t\t {\n" + << "\t\t const real_t ang = atan2(yi, xi);\n" + << "\t\t const real_t s = sin(ang);\n" + << "\t\t const real_t c = cos(ang);\n" + << "\t\t vOut.x = fma(weight, rdc * c, x);\n" + << "\t\t vOut.y = fma(weight, rdc * s, y);\n" + << "\t\t }\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t vOut.x = fma(weight, xi, x);\n" + << "\t\t vOut.y = fma(weight, yi, y);\n" + << "\t\t}\n" + << "\t}\n"; return ss.str(); } @@ -2283,7 +2280,7 @@ protected: m_Params.push_back(ParamWithName(&m_X, prefix + "circlecrop_x")); m_Params.push_back(ParamWithName(&m_Y, prefix + "circlecrop_y")); m_Params.push_back(ParamWithName(&m_ScatterArea, prefix + "circlecrop_scatter_area")); - m_Params.push_back(ParamWithName(&m_Zero, prefix + "circlecrop_zero", 1, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Zero, prefix + "circlecrop_zero", 1, eParamType::REAL, 0, 1)); m_Params.push_back(ParamWithName(true, &m_Ca, prefix + "circlecrop_ca"));//Precalc. } @@ -2391,7 +2388,7 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Inner, prefix + "circlecrop2_inner", T(0.5))); m_Params.push_back(ParamWithName(&m_Outer, prefix + "circlecrop2_outer", 1)); - m_Params.push_back(ParamWithName(&m_Zero, prefix + "circlecrop2_zero", 1, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Zero, prefix + "circlecrop2_zero", 1, eParamType::REAL, 0, 1)); m_Params.push_back(ParamWithName(true, &m_In, prefix + "circlecrop2_in"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Out, prefix + "circlecrop2_out")); m_Params.push_back(ParamWithName(true, &m_OutWeight, prefix + "circlecrop2_out_weight")); @@ -3000,7 +2997,9 @@ public: helper.Out.x = (x * re + y * im) * r; helper.Out.y = (y * re - x * im) * r; helper.Out.z = (z * m_Weight) / c; - outPoint.m_ColorX = Clamp(outPoint.m_ColorX + m_DcAdjust * c, 0, 1); + + if (Compat::m_Compat) + outPoint.m_ColorX = Clamp(outPoint.m_ColorX + m_DcAdjust * c, 0, 1); } virtual string OpenCLString() const override @@ -3020,21 +3019,27 @@ public: string dcAdjust = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string powerInv = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\tconst real_t x = Powq4c(vIn.x, " << power << ");\n" - << "\t\tconst real_t y = Powq4c(vIn.y, " << power << ");\n" - << "\t\tconst real_t z = Powq4c(vIn.z, " << power << ");\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t power = " << power << ";\n" + << "\t\treal_t c1 = " << c1 << ";\n" + << "\t\tconst real_t x = Powq4c(vIn.x, power);\n" + << "\t\tconst real_t y = Powq4c(vIn.y, power);\n" + << "\t\tconst real_t z = Powq4c(vIn.z, power);\n" << "\t\tconst real_t d = fma(x, x, -SQR(y));\n" - << "\t\tconst real_t re = Spread(fma(" << c1 << ", x, " << c2 << " * d), " << sx << ") + (real_t)(1.0);\n" - << "\t\tconst real_t im = Spread(fma(" << c1 << ", y, " << c2x2 << " * x * y), " << sy << ");\n" + << "\t\tconst real_t re = Spread(fma(c1, x, " << c2 << " * d), " << sx << ") + (real_t)(1.0);\n" + << "\t\tconst real_t im = Spread(fma(c1, y, " << c2x2 << " * x * y), " << sy << ");\n" << "\t\treal_t c = Zeps(Powq4c(fma(re, re, SQR(im)), " << powerInv << "));\n" << "\n" - << "\t\tconst real_t r = " << weight << " / c;\n" + << "\t\tconst real_t r = weight / c;\n" << "\n" << "\t\tvOut.x = fma(x, re, y * im) * r;\n" << "\t\tvOut.y = fma(y, re, -(x * im)) * r;\n" - << "\t\tvOut.z = (z * " << weight << ") / c;\n" - << "\t\toutPoint->m_ColorX = clamp(fma(" << dcAdjust << ", c, outPoint->m_ColorX), (real_t)(0.0), (real_t)(1.0));\n" - << "\t}\n"; + << "\t\tvOut.z = (z * weight) / c;\n"; + + if (Compat::m_Compat) + ss << "\t\toutPoint->m_ColorX = clamp(fma(" << dcAdjust << ", c, outPoint->m_ColorX), (real_t)(0.0), (real_t)(1.0));\n"; + + ss << "\t}\n"; return ss.str(); } @@ -4404,7 +4409,7 @@ protected: string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_P, prefix + "blur_heart_p", T(0.5))); - m_Params.push_back(ParamWithName(&m_A, prefix + "blur_heart_a", T(-T(0.6)))); + m_Params.push_back(ParamWithName(&m_A, prefix + "blur_heart_a", T(-0.6))); m_Params.push_back(ParamWithName(&m_B, prefix + "blur_heart_b", T(0.7))); } @@ -4430,9 +4435,9 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - int extended = int(m_Extended); + bool extended = int(m_Extended) == 0 || !Compat::m_Compat; T seed = m_AbsSeed; - T r = -m_Rotation; + T r; T r0 = 0; T r1 = 0; T tileType = 0; @@ -4445,7 +4450,6 @@ public: T y = helper.In.y * m_Scale; int intx = int(Round(x)); int inty = int(Round(y)); - int randiter; r = x - intx; if (r < 0) @@ -4467,24 +4471,22 @@ public: tileType = 1; else { - if (extended == 0) + if (extended) { - T xrand = Round(helper.In.x); - T yrand = Round(helper.In.y); - xrand = xrand * m_Seed2; - yrand = yrand * m_Seed2; + T xrand = Round(helper.In.x) * m_Seed2; + T yrand = Round(helper.In.y) * m_Seed2; niter = xrand + yrand + xrand * yrand; - randInt = (niter + seed) * m_Seed2 / 2; + randInt = (niter + seed) * m_Seed2 * T(0.5); randInt = fmod((randInt * multiplier + offset), modBase); } else { + int randiter = 0; int xrand = int(Round(helper.In.x)); int yrand = int(Round(helper.In.y)); seed = T(Floor(seed)); - niter = T(abs(xrand + yrand + xrand * yrand)); + niter = T(std::abs(xrand + yrand + xrand * yrand)); randInt = seed + niter; - randiter = 0; while (randiter < niter && randiter < 20)//Allow it to escape. { @@ -4496,34 +4498,38 @@ public: tileType = fmod(randInt, T(2)); } + T xval1, xval2; + //Drawing the points. - if (extended == 0)//Fast drawmode + if (extended)//Fast drawmode. { if (tileType < 1) { - r0 = std::pow((pow(std::abs(x), m_Exponent) + std::pow(std::abs(y), m_Exponent)), m_OneOverEx); - r1 = std::pow((pow(std::abs(x - 1), m_Exponent) + std::pow(std::abs(y - 1), m_Exponent)), m_OneOverEx); + xval1 = x; + xval2 = x - 1; } else { - r0 = std::pow((pow(std::abs(x - 1), m_Exponent) + std::pow(std::abs(y), m_Exponent)), m_OneOverEx); - r1 = std::pow((pow(std::abs(x), m_Exponent) + std::pow(std::abs(y - 1), m_Exponent)), m_OneOverEx); + xval1 = x - 1; + xval2 = x; } } - else//Slow drawmode + else//Slow drawmode. { if (tileType == 1) { - r0 = std::pow((std::pow(std::abs(x), m_Exponent) + std::pow(std::abs(y), m_Exponent)), m_OneOverEx); - r1 = std::pow((std::pow(std::abs(x - 1), m_Exponent) + std::pow(std::abs(y - 1), m_Exponent)), m_OneOverEx); + xval1 = x; + xval2 = x - 1; } else { - r0 = std::pow((std::pow(std::abs(x - 1), m_Exponent) + std::pow(std::abs(y), m_Exponent)), m_OneOverEx); - r1 = std::pow((std::pow(std::abs(x), m_Exponent) + std::pow(std::abs(y - 1), m_Exponent)), m_OneOverEx); + xval1 = x - 1; + xval2 = x; } } + r0 = std::pow((std::pow(std::abs(xval1), m_Exponent) + std::pow(std::abs(y), m_Exponent)), m_OneOverEx); + r1 = std::pow((std::pow(std::abs(xval2), m_Exponent) + std::pow(std::abs(y - 1), m_Exponent)), m_OneOverEx); r = std::abs(r0 - T(0.5)) * m_OneOverRmax; if (r < 1) @@ -4569,7 +4575,11 @@ public: ss << "\t{\n" << "\t\tint extended = (int)" << extended << ";\n" << "\t\treal_t seed = " << absSeed << ";\n" - << "\t\treal_t r = -" << rotation << ";\n" + << "\t\treal_t seed2 = " << seed2 << ";\n" + << "\t\treal_t exponent = " << exponent << ";\n" + << "\t\treal_t oneOverEx = " << oneOverEx << ";\n" + << "\t\treal_t size = " << size << ";\n" + << "\t\treal_t oneOverRmax = " << oneOverRmax << ";\n" << "\t\treal_t r0 = 0;\n" << "\t\treal_t r1 = 0;\n" << "\t\treal_t tileType = 0;\n" @@ -4582,9 +4592,7 @@ public: << "\t\treal_t y = vIn.y * " << scale << ";\n" << "\t\tint intx = (int)Round(x);\n" << "\t\tint inty = (int)Round(y);\n" - << "\t\tint randiter;\n" - << "\n" - << "\t\tr = x - intx;\n" + << "\t\treal_t r = x - intx;\n" << "\n" << "\t\tif (r < 0)\n" << "\t\t x = 1 + r;\n" @@ -4603,71 +4611,84 @@ public: << "\t\telse if (seed == 1)\n" << "\t\t tileType = 1;\n" << "\t\telse\n" - << "\t\t{\n" - << "\t\t if (extended == 0)\n" - << "\t\t {\n" - << "\t\t real_t xrand = Round(vIn.x);\n" - << "\t\t real_t yrand = Round(vIn.y);\n" - << "\n" - << "\t\t xrand = xrand * " << seed2 << ";\n" - << "\t\t yrand = yrand * " << seed2 << ";\n" + << "\t\t{\n"; + + if (Compat::m_Compat) + ss << "\t\t if (extended == 0)\n" + << "\t\t {\n"; + + ss << "\t\t real_t xrand = Round(vIn.x) * seed2;\n" + << "\t\t real_t yrand = Round(vIn.y) * seed2;\n" << "\t\t niter = fma(xrand, yrand, xrand + yrand);\n" - << "\t\t randInt = (niter + seed) * " << seed2 << " / 2;\n" - << "\t\t randInt = fmod(fma(randInt, multiplier, offset), modBase);\n" + << "\t\t randInt = (niter + seed) * seed2 * (real_t)(0.5);\n" + << "\t\t randInt = fmod(fma(randInt, multiplier, offset), modBase);\n"; + + if (Compat::m_Compat) + ss << "\t\t }\n" + << "\t\t else\n" + << "\t\t {\n" + << "\t\t int xrand = (int)Round(vIn.x);\n" + << "\t\t int yrand = (int)Round(vIn.y);\n" + << "\n" + << "\t\t seed = floor(seed);\n" + << "\t\t niter = (real_t)abs(xrand + yrand + xrand * yrand);\n" + << "\t\t randInt = seed + niter;\n" + << "\t\t int randiter = 0;\n" + << "\n" + << "\t\t while (randiter < niter && randiter < 20)\n" + << "\t\t {\n" + << "\t\t randiter++;\n" + << "\t\t randInt = fmod(fma(randInt, multiplier, offset), modBase);\n" + << "\t\t }\n" + << "\t\t }\n" + << "\n"; + + ss << "\t\t tileType = fmod(randInt, 2);\n" + << "\t\t}\n" + << "\n" + << "\t\treal_t xval1, xval2;\n" + << "\n"; + + if (Compat::m_Compat) + ss << "\t\tif(extended == 0)\n" + << "\t\t{\n"; + + ss << "\t\t if (tileType < 1)\n" + << "\t\t {\n" + << "\t\t xval1 = x;\n" + << "\t\t xval2 = x - 1;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" - << "\t\t int xrand = (int)Round(vIn.x);\n" - << "\t\t int yrand = (int)Round(vIn.y);\n" - << "\n" - << "\t\t seed = floor(seed);\n" - << "\t\t niter = (real_t)abs(xrand + yrand + xrand * yrand);\n" - << "\t\t randInt = seed + niter;\n" - << "\t\t randiter = 0;\n" - << "\n" - << "\t\t while (randiter < niter && randiter < 20)\n" - << "\t\t {\n" - << "\t\t randiter++;\n" - << "\t\t randInt = fmod((randInt * multiplier + offset), modBase);\n" - << "\t\t }\n" - << "\t\t }\n" - << "\n" - << "\t\t tileType = fmod(randInt, 2);\n" - << "\t\t}\n" - << "\n" - << "\t\tif (extended == 0)\n" - << "\t\t{\n" - << "\t\t if (tileType < 1)\n" - << "\t\t {\n" - << "\t\t r0 = pow((pow(fabs(x ), " << exponent << ") + pow(fabs(y ), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t r1 = pow((pow(fabs(x - 1), " << exponent << ") + pow(fabs(y - 1), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t }\n" - << "\t\t else\n" - << "\t\t {\n" - << "\t\t r0 = pow((pow(fabs(x - 1), " << exponent << ") + pow(fabs(y ), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t r1 = pow((pow(fabs(x ), " << exponent << ") + pow(fabs(y - 1), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t }\n" - << "\t\t}\n" - << "\t\telse\n" - << "\t\t{\n" - << "\t\t if (tileType == 1)\n" - << "\t\t {\n" - << "\t\t r0 = pow((pow(fabs(x ), " << exponent << ") + pow(fabs(y ), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t r1 = pow((pow(fabs(x - 1), " << exponent << ") + pow(fabs(y - 1), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t }\n" - << "\t\t else\n" - << "\t\t {\n" - << "\t\t r0 = pow((pow(fabs(x - 1), " << exponent << ") + pow(fabs(y ), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t r1 = pow((pow(fabs(x ), " << exponent << ") + pow(fabs(y - 1), " << exponent << ")), " << oneOverEx << ");\n" - << "\t\t }\n" - << "\t\t}\n" - << "\n" - << "\t\tr = fabs(r0 - (real_t)(0.5)) * " << oneOverRmax << ";\n" + << "\t\t xval1 = x - 1;\n" + << "\t\t xval2 = x;\n" + << "\t\t }\n"; + + if (Compat::m_Compat) + ss << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t if (tileType == 1)\n" + << "\t\t {\n" + << "\t\t xval1 = x;\n" + << "\t\t xval2 = x - 1;\n" + << "\t\t }\n" + << "\t\t else\n" + << "\t\t {\n" + << "\t\t xval1 = x - 1;\n" + << "\t\t xval2 = x;\n" + << "\t\t }\n" + << "\t\t}\n"; + + ss << "\n" + << "\t\tr0 = pow((pow(fabs(xval1), exponent) + pow(fabs(y ), exponent)), oneOverEx);\n" + << "\t\tr1 = pow((pow(fabs(xval2), exponent) + pow(fabs(y - 1), exponent)), oneOverEx);\n" + << "\t\tr = fabs(r0 - (real_t)(0.5)) * oneOverRmax;\n" << "\n" << "\t\tif (r < 1)\n" << "\t\t{\n" - << "\t\t vOut.x = " << size << " * (x + floor(vIn.x));\n" - << "\t\t vOut.y = " << size << " * (y + floor(vIn.y));\n" + << "\t\t vOut.x = size * (x + floor(vIn.x));\n" + << "\t\t vOut.y = size * (y + floor(vIn.y));\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" @@ -4675,12 +4696,12 @@ public: << "\t\t vOut.y = (real_t)(0.0);\n" << "\t\t}\n" << "\n" - << "\t\tr = fabs(r1 - (real_t)(0.5)) * " << oneOverRmax << ";\n" + << "\t\tr = fabs(r1 - (real_t)(0.5)) * oneOverRmax;\n" << "\n" << "\t\tif (r < 1)\n" << "\t\t{\n" - << "\t\t vOut.x += " << size << " * (x + floor(vIn.x));\n" - << "\t\t vOut.y += " << size << " * (y + floor(vIn.y));\n" + << "\t\t vOut.x += size * (x + floor(vIn.x));\n" + << "\t\t vOut.y += size * (y + floor(vIn.y));\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = " << DefaultZCl() @@ -4695,11 +4716,13 @@ public: virtual void Precalc() override { + m_Exponent = Clamp(m_Exponent, EPS, 2); + m_ArcWidth = Clamp(m_Exponent, EPS, 1); m_OneOverEx = 1 / m_Exponent; m_AbsSeed = std::abs(m_Seed); - m_Seed2 = std::sqrt(Zeps(m_AbsSeed + (m_AbsSeed / 2))) / Zeps((m_AbsSeed * T(0.5))) * T(0.25); - m_OneOverRmax = 1 / (T(0.5) * (std::pow(T(2), 1 / m_Exponent) - 1) * m_ArcWidth); - m_Scale = (std::cos(-m_Rotation) - std::sin(-m_Rotation)) / m_Weight; + m_Seed2 = std::sqrt(Zeps(m_AbsSeed * T(1.5))) / Zeps((m_AbsSeed * T(0.5))) * T(0.25); + m_OneOverRmax = 1 / (T(0.5) * (std::pow(T(2), m_OneOverEx) - 1) * m_ArcWidth); + m_Scale = (std::cos(m_Rotation) + std::sin(m_Rotation)) / m_Weight; } protected: @@ -4707,11 +4730,11 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Extended, prefix + "Truchet_extended", 0, eParamType::INTEGER, 0, 1)); - m_Params.push_back(ParamWithName(&m_Exponent, prefix + "Truchet_exponent", 2, eParamType::REAL_CYCLIC, T(0.001), 2)); - m_Params.push_back(ParamWithName(&m_ArcWidth, prefix + "Truchet_arc_width", T(0.5), eParamType::REAL_CYCLIC, T(0.001), 1)); + m_Params.push_back(ParamWithName(&m_Extended, prefix + "Truchet_extended", 1)); + m_Params.push_back(ParamWithName(&m_Exponent, prefix + "Truchet_exponent", 2, eParamType::REAL_NONZERO, EPS, 2)); + m_Params.push_back(ParamWithName(&m_ArcWidth, prefix + "Truchet_arc_width", T(0.5), eParamType::REAL_NONZERO, EPS, 1)); m_Params.push_back(ParamWithName(&m_Rotation, prefix + "Truchet_rotation")); - m_Params.push_back(ParamWithName(&m_Size, prefix + "Truchet_size", 1, eParamType::REAL_CYCLIC, T(0.001), 10)); + m_Params.push_back(ParamWithName(&m_Size, prefix + "Truchet_size", 1, eParamType::REAL, EPS)); m_Params.push_back(ParamWithName(&m_Seed, prefix + "Truchet_seed", 50)); m_Params.push_back(ParamWithName(true, &m_OneOverEx, prefix + "Truchet_one_over_ex"));//Precalc. m_Params.push_back(ParamWithName(true, &m_AbsSeed, prefix + "Truchet_abs_seed")); diff --git a/Source/Ember/Variations05.h b/Source/Ember/Variations05.h index b4edeb5..809c735 100644 --- a/Source/Ember/Variations05.h +++ b/Source/Ember/Variations05.h @@ -1429,51 +1429,90 @@ template class Loonie2Variation : public ParametricVariation { public: + using Variation::m_NeedPrecalcSumSquares; + using Variation::m_NeedPrecalcSqrtSumSquares; + Loonie2Variation(T weight = 1.0) : ParametricVariation("loonie2", eVariationId::VAR_LOONIE2, weight, true, true) { Init(); + m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; } PARVARCOPY(Loonie2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - int i; - T xrt = helper.In.x, yrt = helper.In.y, swp; - T r2 = xrt * m_Coss + std::abs(yrt) * m_Sins; - T circle = helper.m_PrecalcSqrtSumSquares; - - for (i = 0; i < m_Sides - 1; i++) + if (Compat::m_Compat) { - swp = xrt * m_Cosa - yrt * m_Sina; - yrt = xrt * m_Sina + yrt * m_Cosa; - xrt = swp; - r2 = std::max(r2, xrt * m_Coss + std::abs(yrt) * m_Sins); - } + int i; + T xrt = helper.In.x, yrt = helper.In.y, swp; + T r2 = xrt * m_Coss + std::abs(yrt) * m_Sins; + T circle = helper.m_PrecalcSqrtSumSquares; - r2 = r2 * m_Cosc + circle * m_Sinc; + for (i = 0; i < m_Sides - 1; i++) + { + swp = xrt * m_Cosa - yrt * m_Sina; + yrt = xrt * m_Sina + yrt * m_Cosa; + xrt = swp; + r2 = std::max(r2, xrt * m_Coss + std::abs(yrt) * m_Sins); + } - if (i > 1) - r2 = SQR(r2); - else - r2 = std::abs(r2) * r2; + r2 = r2 * m_Cosc + circle * m_Sinc; - if (r2 > 0 && (r2 < m_W2)) - { - T r = m_Weight * std::sqrt(std::abs(m_W2 / r2 - 1)); - helper.Out.x = r * helper.In.x; - helper.Out.y = r * helper.In.y; - } - else if (r2 < 0) - { - T r = m_Weight / std::sqrt(std::abs(m_W2 / r2) - 1); - helper.Out.x = r * helper.In.x; - helper.Out.y = r * helper.In.y; + if (i > 1) + r2 = SQR(r2); + else + r2 = std::abs(r2) * r2; + + if (r2 > 0 && (r2 < m_W2)) + { + T r = m_Weight * std::sqrt(std::abs(m_W2 / r2 - 1)); + helper.Out.x = r * helper.In.x; + helper.Out.y = r * helper.In.y; + } + else if (r2 < 0) + { + T r = m_Weight / std::sqrt(std::abs(m_W2 / r2) - 1); + helper.Out.x = r * helper.In.x; + helper.Out.y = r * helper.In.y; + } + else + { + helper.Out.x = m_Weight * helper.In.x; + 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; + T r2 = helper.m_PrecalcSumSquares; + T r = r2 < T(1) ? std::sqrt(1 / Zeps(r2) - 1) : T(1); + T newX = helper.In.x * r; + T newY = helper.In.y * r; + T dang = (std::atan2(newY, newX) + T(M_PI)) / m_Alpha; + T rad = std::sqrt(SQR(newX) + SQR(newY)); + T zang1 = T(Floor(dang)); + T xang1 = dang - zang1; + T xang2, zang, sign; + + if (xang1 > T(0.5)) + { + xang2 = 1 - xang1; + zang = zang1 + 1; + sign = -1; + } + else + { + xang2 = xang1; + zang = zang1; + sign = 1; + } + + T xang = std::atan(xang2 * m_TanHalfAlpha2) / m_Alpha; + T coeff = 1 / Zeps(std::cos(xang * m_Alpha)); + T ang = (zang + sign * xang) * m_Alpha - T(M_PI); + T temp = m_Weight * coeff * rad; + helper.Out.x = temp * std::cos(ang); + helper.Out.y = temp * std::sin(ang); } helper.Out.z = DefaultZ(helper); @@ -1486,72 +1525,137 @@ public: ss2 << "_" << XformIndexInEmber() << "]"; string weight = WeightDefineString(); string index = ss2.str(); - string sides = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string star = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string circle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string w2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string sina = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string cosa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string sins = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string coss = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string sinc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string cosc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - ss << "\t{\n" - << "\t\tint i;\n" - << "\t\treal_t xrt = vIn.x, yrt = vIn.y, swp;\n" - << "\t\treal_t r2 = fma(xrt, " << coss << ", fabs(yrt) * " << sins << ");\n" - << "\t\treal_t circle = precalcSqrtSumSquares;\n" - << "\n" - << "\t\tfor (i = 0; i < " << sides << " - 1; i++)\n" - << "\t\t{\n" - << "\t\t swp = fma(xrt, " << cosa << ", -(yrt * " << sina << "));\n" - << "\t\t yrt = fma(xrt, " << sina << ", yrt * " << cosa << ");\n" - << "\t\t xrt = swp;\n" - << "\n" - << "\t\t r2 = max(r2, fma(xrt, " << coss << ", fabs(yrt) * " << sins << "));\n" - << "\t\t}\n" - << "\n" - << "\t\tr2 = fma(r2, " << cosc << ", circle * " << sinc << ");\n" - << "\n" - << "\t\tif (i > 1)\n" - << "\t\t r2 = SQR(r2);\n" - << "\t\telse\n" - << "\t\t r2 = fabs(r2) * r2;\n" - << "\n" - << "\t\tif (r2 > 0 && (r2 < " << w2 << "))\n" - << "\t\t{\n" - << "\t\t real_t r = " << weight << " * sqrt(fabs(" << w2 << " / r2 - 1));\n" - << "\n" - << "\t\t vOut.x = r * vIn.x;\n" - << "\t\t vOut.y = r * vIn.y;\n" - << "\t\t}\n" - << "\t\telse if (r2 < 0)\n" - << "\t\t{\n" - << "\t\t real_t r = " << weight << " / sqrt(fabs(" << w2 << " / r2) - 1);\n" - << "\n" - << "\t\t vOut.x = r * vIn.x;\n" - << "\t\t vOut.y = r * vIn.y;\n" - << "\t\t}\n" - << "\t\telse\n" - << "\t\t{\n" - << "\t\t vOut.x = " << weight << " * vIn.x;\n" - << "\t\t vOut.y = " << weight << " * vIn.y;\n" - << "\t\t}\n" - << "\n" - << "\t\tvOut.z = " << DefaultZCl() + string sides = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string star = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string circle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string w2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string sina = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string cosa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string sins = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string coss = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string sinc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string cosc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string alpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string tanhalfalpha2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + + if (Compat::m_Compat) + { + ss << "\t{\n" + << "\t\tint i;\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t coss = " << coss << ";\n" + << "\t\treal_t sins = " << sins << ";\n" + << "\t\treal_t sina = " << sina << ";\n" + << "\t\treal_t cosa = " << cosa << ";\n" + << "\t\treal_t w2 = " << w2 << ";\n" + << "\t\treal_t xrt = vIn.x, yrt = vIn.y, swp;\n" + << "\t\treal_t r2 = fma(xrt, coss, fabs(yrt) * sins);\n" + << "\t\treal_t circle = precalcSqrtSumSquares;\n" + << "\n" + << "\t\tfor (i = 0; i < " << sides << " - 1; i++)\n" + << "\t\t{\n" + << "\t\t swp = fma(xrt, cosa, -(yrt * sina));\n" + << "\t\t yrt = fma(xrt, sina, yrt * cosa);\n" + << "\t\t xrt = swp;\n" + << "\n" + << "\t\t r2 = max(r2, fma(xrt, coss, fabs(yrt) * sins));\n" + << "\t\t}\n" + << "\n" + << "\t\tr2 = fma(r2, " << cosc << ", circle * " << sinc << ");\n" + << "\n" + << "\t\tif (i > 1)\n" + << "\t\t r2 = SQR(r2);\n" + << "\t\telse\n" + << "\t\t r2 = fabs(r2) * r2;\n" + << "\n" + << "\t\tif (r2 > 0 && (r2 < w2))\n" + << "\t\t{\n" + << "\t\t real_t r = weight * sqrt(fabs(w2 / r2 - 1));\n" + << "\n" + << "\t\t vOut.x = r * vIn.x;\n" + << "\t\t vOut.y = r * vIn.y;\n" + << "\t\t}\n" + << "\t\telse if (r2 < 0)\n" + << "\t\t{\n" + << "\t\t real_t r = weight / sqrt(fabs(w2 / r2) - 1);\n" + << "\n" + << "\t\t vOut.x = r * vIn.x;\n" + << "\t\t vOut.y = r * vIn.y;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t vOut.x = weight * vIn.x;\n" + << "\t\t vOut.y = weight * vIn.y;\n" + << "\t\t}\n"; + } + else + { + ss << "\t{\n" + << "\t\treal_t alpha = " << alpha << ";\n" + << "\t\treal_t r2 = precalcSumSquares;\n" + << "\t\treal_t r = r2 < (real_t)(1.0) ? sqrt(1 / Zeps(r2) - 1) : (real_t)(1.0);\n" + << "\t\treal_t newX = vIn.x * r;\n" + << "\t\treal_t newY = vIn.y * r;\n" + << "\t\treal_t dang = (atan2(newY, newX) + MPI) / alpha;\n" + << "\t\treal_t rad = sqrt(SQR(newX) + SQR(newY));\n" + << "\t\treal_t zang1 = floor(dang);\n" + << "\t\treal_t xang1 = dang - zang1;\n" + << "\t\treal_t xang2, zang, sign;\n" + << "\n" + << "\t\tif (xang1 > 0.5)\n" + << "\t\t{\n" + << "\t\t xang2 = 1 - xang1;\n" + << "\t\t zang = zang1 + 1;\n" + << "\t\t sign = -1;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t xang2 = xang1;\n" + << "\t\t zang = zang1;\n" + << "\t\t sign = 1;\n" + << "\t\t}\n" + << "\n" + << "\t\treal_t xang = atan(xang2 * " << tanhalfalpha2 << ") / alpha;\n" + << "\t\treal_t coeff = 1 / Zeps(cos(xang * alpha));\n" + << "\t\treal_t ang = (zang + sign * xang) * alpha - MPI;\n" + << "\t\treal_t temp = " << weight << " * coeff * rad;\n" + << "\t\tvOut.x = temp * cos(ang);\n" + << "\t\tvOut.y = temp * sin(ang);\n"; + } + + ss << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } virtual void Precalc() override { - auto a = M_2PI / m_Sides; - auto s = T(-M_PI_2) * m_Star; - auto c = T(M_PI_2) * m_Circle; - m_W2 = SQR(m_Weight); - sincos(a, &m_Sina, &m_Cosa); - sincos(s, &m_Sins, &m_Coss); - sincos(c, &m_Sinc, &m_Cosc); + if (Compat::m_Compat) + { + auto a = M_2PI / m_Sides; + auto s = T(-M_PI_2) * m_Star; + auto c = T(M_PI_2) * m_Circle; + m_W2 = SQR(m_Weight); + sincos(a, &m_Sina, &m_Cosa); + sincos(s, &m_Sins, &m_Coss); + sincos(c, &m_Sinc, &m_Cosc); + } + else + { + m_Alpha = M_2PI / Zeps(m_Power); + m_TanHalfAlpha2 = std::tan(m_Alpha * T(0.5)) * 2; + } + + m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; + } + + virtual vector OpenCLGlobalFuncNames() const override + { + if (Compat::m_Compat) + return vector { }; + else + return vector { "Zeps" }; } protected: @@ -1562,6 +1666,7 @@ protected: m_Params.push_back(ParamWithName(&m_Sides, prefix + "loonie2_sides", 4, eParamType::INTEGER, 1, 50)); m_Params.push_back(ParamWithName(&m_Star, prefix + "loonie2_star", 0, eParamType::REAL, -1, 1)); m_Params.push_back(ParamWithName(&m_Circle, prefix + "loonie2_circle", 0, eParamType::REAL, -1, 1)); + m_Params.push_back(ParamWithName(&m_Power, prefix + "loonie2_power", 4)); m_Params.push_back(ParamWithName(true, &m_W2, prefix + "loonie2_w2"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Sina, prefix + "loonie2_sina")); m_Params.push_back(ParamWithName(true, &m_Cosa, prefix + "loonie2_cosa")); @@ -1569,12 +1674,15 @@ protected: m_Params.push_back(ParamWithName(true, &m_Coss, prefix + "loonie2_coss")); m_Params.push_back(ParamWithName(true, &m_Sinc, prefix + "loonie2_sinc")); m_Params.push_back(ParamWithName(true, &m_Cosc, prefix + "loonie2_cosc")); + m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "loonie2_alpha")); + m_Params.push_back(ParamWithName(true, &m_TanHalfAlpha2, prefix + "loonie2_tan_half_alpha2")); } private: T m_Sides; T m_Star; T m_Circle; + T m_Power; T m_W2;//Precalc. T m_Sina; T m_Cosa; @@ -1582,6 +1690,8 @@ private: T m_Coss; T m_Sinc; T m_Cosc; + T m_Alpha; + T m_TanHalfAlpha2; }; /// @@ -2485,9 +2595,9 @@ public: default: scale = Clamp(rs, 0, T(0.9)) + T(0.1); denom = 1 / scale; - helper.Out.x = m_Weight * Lerp(helper.In.x, std::floor(helper.In.x * denom) + scale * ax, m_MulX * rs) + m_MulX * std::pow(ax, m_BoxPow) * rs * denom;//m_BoxPow should be an integer value held in T, - helper.Out.y = m_Weight * Lerp(helper.In.y, std::floor(helper.In.y * denom) + scale * ay, m_MulY * rs) + m_MulY * std::pow(ay, m_BoxPow) * rs * denom;//so std::abs() shouldn't be necessary. - helper.Out.z = m_Weight * Lerp(helper.In.z, std::floor(helper.In.z * denom) + scale * az, m_MulZ * rs) + m_MulZ * std::pow(az, m_BoxPow) * rs * denom; + helper.Out.x = m_Weight * Lerp(helper.In.x, Floor(helper.In.x * denom) + scale * ax, m_MulX * rs) + m_MulX * std::pow(ax, m_BoxPow) * rs * denom;//m_BoxPow should be an integer value held in T, + helper.Out.y = m_Weight * Lerp(helper.In.y, Floor(helper.In.y * denom) + scale * ay, m_MulY * rs) + m_MulY * std::pow(ay, m_BoxPow) * rs * denom;//so std::abs() shouldn't be necessary. + helper.Out.z = m_Weight * Lerp(helper.In.z, Floor(helper.In.z * denom) + scale * az, m_MulZ * rs) + m_MulZ * std::pow(az, m_BoxPow) * rs * denom; break; } } @@ -2785,13 +2895,13 @@ protected: m_Params.push_back(ParamWithName(&m_MinDist, prefix + "falloff2_mindist", T(0.5))); m_Params.push_back(ParamWithName(&m_MulX, prefix + "falloff2_mul_x", 1)); m_Params.push_back(ParamWithName(&m_MulY, prefix + "falloff2_mul_y", 1)); - m_Params.push_back(ParamWithName(&m_MulZ, prefix + "falloff2_mul_z", 0)); - m_Params.push_back(ParamWithName(&m_MulC, prefix + "falloff2_mul_c", 0)); + m_Params.push_back(ParamWithName(&m_MulZ, prefix + "falloff2_mul_z")); + m_Params.push_back(ParamWithName(&m_MulC, prefix + "falloff2_mul_c")); m_Params.push_back(ParamWithName(&m_X0, prefix + "falloff2_x0")); m_Params.push_back(ParamWithName(&m_Y0, prefix + "falloff2_y0")); m_Params.push_back(ParamWithName(&m_Z0, prefix + "falloff2_z0")); - m_Params.push_back(ParamWithName(&m_Invert, prefix + "falloff2_invert", 0, eParamType::INTEGER, 0, 1)); - m_Params.push_back(ParamWithName(&m_Type, prefix + "falloff2_type", 0, eParamType::INTEGER, 0, 2)); + m_Params.push_back(ParamWithName(&m_Invert, prefix + "falloff2_invert", 0, eParamType::REAL, 0, 1)); + m_Params.push_back(ParamWithName(&m_Type, prefix + "falloff2_type", 0, eParamType::REAL, 0, 2)); m_Params.push_back(ParamWithName(true, &m_RMax, prefix + "falloff2_rmax"));//Precalc. } diff --git a/Source/Ember/Variations06.h b/Source/Ember/Variations06.h index 9ca885e..432676a 100644 --- a/Source/Ember/Variations06.h +++ b/Source/Ember/Variations06.h @@ -787,7 +787,7 @@ public: if (int(m_NumEdges) % 4 == 0) m_AdjustedWeight = m_Weight / Zeps(std::sqrt(2 - 2 * std::cos(m_MidAngle * (m_NumEdges / 2 - 1))) / 2); else - m_AdjustedWeight = m_Weight / Zeps(std::sqrt(2 - 2 * std::cos(m_MidAngle * std::floor((m_NumEdges / 2)))) / 2); + m_AdjustedWeight = m_Weight / Zeps(std::sqrt(2 - 2 * std::cos(m_MidAngle * Floor((m_NumEdges / 2)))) / 2); } else m_AdjustedWeight = m_Weight; @@ -3721,8 +3721,8 @@ public: T theta = M_2PI * rand.Frand01(); u.x = blurr * std::sin(theta); u.y = blurr * std::cos(theta); - cv.x = int(std::floor(u.x / m_HalfCellSize)); - cv.y = int(std::floor(u.y / m_HalfCellSize)); + cv.x = int(Floor(u.x / m_HalfCellSize)); + cv.y = int(Floor(u.y / m_HalfCellSize)); for (int di = -1; di < 2; di++) { @@ -4483,7 +4483,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Power, prefix + "smartcrop_power", 4)); //Original used a prefix of scrop_, which is incompatible with Ember's design. + m_Params.push_back(ParamWithName(&m_Power, prefix + "smartcrop_power", 4));//Original used a prefix of scrop_, which is incompatible with Ember's design. m_Params.push_back(ParamWithName(&m_Radius, prefix + "smartcrop_radius", 1)); m_Params.push_back(ParamWithName(&m_Roundstr, prefix + "smartcrop_roundstr")); m_Params.push_back(ParamWithName(&m_Roundwidth, prefix + "smartcrop_roundwidth", 1)); @@ -4492,8 +4492,8 @@ protected: m_Params.push_back(ParamWithName(&m_Scatter, prefix + "smartcrop_scatter")); m_Params.push_back(ParamWithName(&m_Offset, prefix + "smartcrop_offset")); m_Params.push_back(ParamWithName(&m_Rotation, prefix + "smartcrop_rotation")); - m_Params.push_back(ParamWithName(&m_Cropmode, prefix + "smartcrop_cropmode", 1, eParamType::INTEGER, -1, 2)); - m_Params.push_back(ParamWithName(&m_Static, prefix + "smartcrop_static", 1, eParamType::INTEGER, -1, 3)); + m_Params.push_back(ParamWithName(&m_Cropmode, prefix + "smartcrop_cropmode", 1, eParamType::REAL, -1, 2)); + m_Params.push_back(ParamWithName(&m_Static, prefix + "smartcrop_static", 1, eParamType::REAL, -1, 3)); m_Params.push_back(ParamWithName(true, &m_Mode, prefix + "smartcrop_mode"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Radial, prefix + "smartcrop_radial")); m_Params.push_back(ParamWithName(true, &m_WorkRadius, prefix + "smartcrop_work_radius")); diff --git a/Source/Ember/Variations07.h b/Source/Ember/Variations07.h index 46efb27..ae5cb6c 100644 --- a/Source/Ember/Variations07.h +++ b/Source/Ember/Variations07.h @@ -1278,31 +1278,32 @@ public: T niter = xrand + yrand + (xrand * yrand); T randint = (m_Seed + niter) * m_Seed2 * T(0.5); randint = std::fmod((randint * multiplier + offset), modbase); - tiletype = std::fmod(randint, T(2.0)); + tiletype = std::fmod(randint, T(2)); } } - T r0, r1; + T xval1, xval2; - if (tiletype < T(1)) + if (tiletype < 1) { - //Slow drawmode - r0 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx); - r1 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y - 1), m_FinalExponent)), m_OneOverEx); + xval1 = x; + xval2 = x - 1; } else { - r0 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx); - r1 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y - T(1.0)), m_FinalExponent)), m_OneOverEx); + xval1 = x - 1; + xval2 = x; } + T r0 = std::pow((std::pow(std::fabs(xval1), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx); + T r1 = std::pow((std::pow(std::fabs(xval2), m_FinalExponent) + std::pow(std::fabs(y - 1), m_FinalExponent)), m_OneOverEx); T x1, y1; T r00 = fabs(r0 - T(0.5)) / m_Rmax; if (r00 < 1) { - x1 = 2 * (x + std::floor(helper.In.x)); - y1 = 2 * (y + std::floor(helper.In.y)); + x1 = 2 * (x + Floor(helper.In.x)); + y1 = 2 * (y + Floor(helper.In.y)); } else { @@ -1314,8 +1315,8 @@ public: if (r11 < 1) { - helper.Out.x = x1 + (2 * (x + std::floor(helper.In.x))) - helper.In.x; - helper.Out.y = y1 + (2 * (y + std::floor(helper.In.y))) - helper.In.y; + helper.Out.x = x1 + (2 * (x + Floor(helper.In.x))) - helper.In.x; + helper.Out.y = y1 + (2 * (y + Floor(helper.In.y))) - helper.In.y; } else { @@ -1346,7 +1347,12 @@ public: << "\t\treal_t modbase = 65535;\n" << "\t\treal_t multiplier = 32747;\n" << "\t\treal_t offset = 12345;\n" - << "\n" + << "\t\treal_t sscale = " << scale << ";\n" + << "\t\treal_t seed = " << seed << ";\n" + << "\t\treal_t seed2 = " << seed2 << ";\n" + << "\t\treal_t finalexponent = " << finalexponent << ";\n" + << "\t\treal_t oneOverEx = " << oneOverEx << ";\n" + << "\t\treal_t rmax = " << rmax << ";\n" << "\t\treal_t x = vIn.x * " << scale << ";\n" << "\t\treal_t y = vIn.y * " << scale << ";\n" << "\t\treal_t intx = Round(x);\n" @@ -1368,43 +1374,46 @@ public: << "\n" << "\t\treal_t tiletype = 0;\n" << "\n" - << "\t\tif (" << seed << " != 0)\n" + << "\t\tif (seed != 0)\n" << "\t\t{\n" - << "\t\t\tif (" << seed << " == 1)\n" + << "\t\t\tif (seed == 1)\n" << "\t\t\t{\n" - << "\t\t\t\ttiletype = " << seed << ";\n" + << "\t\t\t\ttiletype = seed;\n" << "\t\t\t}\n" << "\t\t\telse\n" << "\t\t\t{\n" << "\t\t\t\treal_t xrand = vIn.x;\n" << "\t\t\t\treal_t yrand = vIn.y;\n" << "\n" - << "\t\t\t\txrand = Round(fabs(xrand)) * " << seed2 << ";\n" - << "\t\t\t\tyrand = Round(fabs(yrand)) * " << seed2 << ";\n" + << "\t\t\t\txrand = Round(fabs(xrand)) * seed2;\n" + << "\t\t\t\tyrand = Round(fabs(yrand)) * seed2;\n" << "\n" << "\t\t\t\treal_t niter = fma(xrand, yrand, xrand + yrand);\n" - << "\t\t\t\treal_t randint = (" << seed << " + niter) * " << seed2 << " * ((real_t) 0.5);\n" + << "\t\t\t\treal_t randint = (seed + niter) * seed2 * (real_t)0.5;\n" << "\n" << "\t\t\t\trandint = fmod(fma(randint, multiplier, offset), modbase);\n" << "\t\t\t\ttiletype = fmod(randint, 2);\n" << "\t\t\t}\n" << "\t\t}\n" << "\n" - << "\t\treal_t r0, r1;\n" + << "\t\treal_t xval1, xval2;\n" << "\n" << "\t\tif (tiletype < 1)\n" << "\t\t{\n" - << "\t\t\tr0 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n" - << "\t\t\tr1 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n" + << "\t\t xval1 = x;\n" + << "\t\t xval2 = x - 1;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" - << "\t\t\tr0 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n" - << "\t\t\tr1 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n" + << "\t\t xval1 = x - 1;\n" + << "\t\t xval2 = x;\n" << "\t\t}\n" << "\n" + << "\t\t\treal_t r0 = pow((pow(fabs(xval1), finalexponent) + pow(fabs(y), finalexponent)), oneOverEx);\n" + << "\t\t\treal_t r1 = pow((pow(fabs(xval2), finalexponent) + pow(fabs(y-1), finalexponent)), oneOverEx);\n" + << "\n" << "\t\treal_t x1, y1;\n" - << "\t\treal_t r00 = fabs(r0 - (real_t) 0.5) / " << rmax << ";\n" + << "\t\treal_t r00 = fabs(r0 - (real_t)0.5) / rmax;\n" << "\n" << "\t\tif (r00 < 1.0)\n" << "\t\t{\n" @@ -1417,7 +1426,7 @@ public: << "\t\t\ty1 = 0;\n" << "\t\t}\n" << "\n" - << "\t\treal_t r11 = fabs(r1 - (real_t) 0.5) / " << rmax << ";\n" + << "\t\treal_t r11 = fabs(r1 - (real_t)0.5) / rmax;\n" << "\n" << "\t\tif (r11 < 1)\n" << "\t\t{\n" @@ -1642,12 +1651,12 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_N, prefix + "Truchet_hex_fill_n", T(3), eParamType::INTEGER)); - m_Params.push_back(ParamWithName(&m_Flipx, prefix + "Truchet_hex_fill_flipx", T(1), eParamType::INTEGER, T(0), T(1))); - m_Params.push_back(ParamWithName(&m_Flipy, prefix + "Truchet_hex_fill_flipy", T(1), eParamType::INTEGER, T(0), T(1))); - m_Params.push_back(ParamWithName(&m_Spreadx, prefix + "Truchet_hex_fill_spreadx", T(1.0))); - m_Params.push_back(ParamWithName(&m_Spready, prefix + "Truchet_hex_fill_spready", T(1.0))); - m_Params.push_back(ParamWithName(&m_Seed, prefix + "Truchet_hex_fill_seed", T(0), eParamType::INTEGER)); + m_Params.push_back(ParamWithName(&m_N, prefix + "Truchet_hex_fill_n", 3, eParamType::INTEGER)); + m_Params.push_back(ParamWithName(&m_Flipx, prefix + "Truchet_hex_fill_flipx", 1, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Flipy, prefix + "Truchet_hex_fill_flipy", 1, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Spreadx, prefix + "Truchet_hex_fill_spreadx", 1)); + m_Params.push_back(ParamWithName(&m_Spready, prefix + "Truchet_hex_fill_spready", 1)); + m_Params.push_back(ParamWithName(&m_Seed, prefix + "Truchet_hex_fill_seed", 0, eParamType::INTEGER)); m_Params.push_back(ParamWithName(true, &m_3nPrecalc, prefix + "Truchet_hex_fill_3n_precalc"));//Precalc. m_Params.push_back(ParamWithName(true, &m_13nPrecalc, prefix + "Truchet_hex_fill_1_3n_precalc")); } @@ -1841,7 +1850,7 @@ public: << "\t\tif (" << seed << " == 1)\n" << "\t\t{\n" << "\t\t if (!((int)rx & 1) && !((int)rz & 1)) \n" - << "\t\t add = M_PI3;\n" + << "\t\t add = MPI3;\n" << "\t\t}\n" << "\t\telse if (" << seed << " >= 2)\n" << "\t\t{\n" @@ -1849,12 +1858,12 @@ public: << "\t\t hash_f = hash_f - floor(hash_f);\n" << "\n" << "\t\t if (hash_f < (real_t)(0.5))\n" - << "\t\t add = M_PI3;\n" + << "\t\t add = MPI3;\n" << "\t\t}\n" << "\n" - << "\t\treal_t angle = atan2(FY, FX) + M_PI6 - add;\n" + << "\t\treal_t angle = atan2(FY, FX) + MPI6 - add;\n" << "\t\treal_t coef = (real_t)(0.47746482927568600730665129011754);\n" - << "\t\treal_t angle2 = floor(angle * coef) / coef + M_PI6 + add;\n" + << "\t\treal_t angle2 = floor(angle * coef) / coef + MPI6 + add;\n" << "\t\treal_t x0 = cos(angle2);\n" << "\t\treal_t y0 = sin(angle2);\n" << "\t\treal_t dist = sqrt(Sqr(FX - x0) + Sqr(FY - y0));\n" @@ -2405,7 +2414,7 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_R, prefix + "cpow3_r", 1)); m_Params.push_back(ParamWithName(&m_D, prefix + "cpow3_d", 1, eParamType::REAL_NONZERO)); - m_Params.push_back(ParamWithName(&m_Divisor, prefix + "cpow3_divisor", 1, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_Divisor, prefix + "cpow3_divisor", 1, eParamType::REAL_NONZERO)); m_Params.push_back(ParamWithName(&m_Spread, prefix + "cpow3_spread", 1)); m_Params.push_back(ParamWithName(true, &m_PrecalcC, prefix + "cpow3_precalc_c"));//Precalc. m_Params.push_back(ParamWithName(true, &m_HalfC, prefix + "cpow3_half_c")); @@ -2692,9 +2701,9 @@ public: T rad = 1 / Zeps(helper.m_PrecalcSumSquares); T x = rad * helper.In.x + m_Shift; T y = rad * helper.In.y; - rad = m_Weight * m_Scale / Zeps(x * x + y * y); + rad = m_Weight * m_Scale / Zeps(SQR(x) + SQR(y)); - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) outPoint.m_X = outPoint.m_Y = outPoint.m_Z = 0;//This variation assigns, instead of summing, so order will matter. helper.Out.x = rad * x + m_Shift; @@ -2717,7 +2726,7 @@ public: << "\t\treal_t y = rad * vIn.y;\n" << "\t\trad = " << weight << " * " << scale << " / Zeps(fma(x, x, SQR(y)));\n"; - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) ss << "\t\toutPoint->m_X = outPoint->m_Y = outPoint->m_Z = 0;\n"; ss << "\t\tvOut.x = fma(rad, x, " << shift << ");\n" @@ -2779,7 +2788,7 @@ public: T cosa = std::cos(angle); T sina = std::sin(angle); - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) outPoint.m_X = outPoint.m_Y = outPoint.m_Z = 0;//This variation assigns, instead of summing, so order will matter. helper.Out.x = cosa * X - sina * Y; @@ -2800,8 +2809,9 @@ public: string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scale2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t fx = vIn.x * " << scale2 << ";\n" - << "\t\treal_t fy = vIn.y * " << scale2 << ";\n" + << "\t\treal_t scale2 = " << scale2 << ";\n" + << "\t\treal_t fx = vIn.x * scale2;\n" + << "\t\treal_t fy = vIn.y * scale2;\n" << "\t\treal_t rad = 1 / Zeps(fma(fx, fx, SQR(fy)));\n" << "\t\treal_t x = fma(rad, fx, " << shift << ");\n" << "\t\treal_t y = rad * fy;\n" @@ -2812,7 +2822,7 @@ public: << "\t\treal_t cosa = cos(angle);\n" << "\t\treal_t sina = sin(angle);\n"; - if (m_VarType == eVariationType::VARTYPE_REG) + if (Compat::m_Compat && m_VarType == eVariationType::VARTYPE_REG) ss << "\t\toutPoint->m_X = outPoint->m_Y = outPoint->m_Z = 0;\n"; ss << "\t\tvOut.x = fma(cosa, X, -(sina * Y));\n" @@ -2845,8 +2855,8 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_P, prefix + "hypershift2_p", 3, eParamType::INTEGER_NONZERO)); - m_Params.push_back(ParamWithName(&m_Q, prefix + "hypershift2_q", 7, eParamType::INTEGER_NONZERO)); + m_Params.push_back(ParamWithName(&m_P, prefix + "hypershift2_p", 3, eParamType::REAL, 2)); + m_Params.push_back(ParamWithName(&m_Q, prefix + "hypershift2_q", 7, eParamType::REAL, 2)); m_Params.push_back(ParamWithName(true, &m_Shift, prefix + "hypershift2_shift"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Scale, prefix + "hypershift2_scale")); m_Params.push_back(ParamWithName(true, &m_Scale2, prefix + "hypershift2_scale2")); @@ -3622,31 +3632,64 @@ template class DepthNgon2Variation : public ParametricVariation { public: + using Variation::m_NeedPrecalcSumSquares; + using Variation::m_NeedPrecalcSqrtSumSquares; + DepthNgon2Variation(T weight = 1.0) : ParametricVariation("depth_ngon2", eVariationId::VAR_DEPTH_NGON2, weight) { Init(); + m_NeedPrecalcSumSquares = m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; } PARVARCOPY(DepthNgon2Variation) virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T bx = 0; - T by = 0; - T rad = std::sqrt(Sqr((helper.In.x - m_X0) / m_OneOverMulXSq) + Sqr((helper.In.y - m_Y0) / m_OneOverMulYSq)); + T bx; + T by; - if (rad > m_Radius) + if (Compat::m_Compat) { - T ang = rand.Frand01() * M_2PI; - T phi = ang - m_Side * Floor(ang / Zeps(m_Side)); + T rad = helper.m_PrecalcSqrtSumSquares; - if (phi > m_HalfSide) - phi -= m_Side; + if (rad > m_Radius) + { + T ang = rand.Frand01() * M_2PI; + T phi = ang - m_Side * Floor(ang / Zeps(m_Side)); - phi = 1 / Zeps(std::cos(phi)); - T aux = phi * m_BlurOver10 * std::exp(std::log(rad - m_Radius) * m_Exp); - bx = aux * std::cos(ang); - by = aux * std::sin(ang); + if (phi > m_HalfSide) + phi -= m_Side; + + phi = 1 / Zeps(std::cos(phi)); + T aux = phi * m_BlurOver10 * (rad - m_Radius); + bx = aux * std::cos(ang); + by = aux * std::sin(ang); + } + else + { + bx = 0; + by = 0; + } + } + else + { + T rad = std::sqrt(Sqr(helper.In.x - m_X0) * m_OneOverMulXSq + Sqr(helper.In.y - m_Y0) * m_OneOverMulYSq); + + if (rad > m_Radius) + { + T ang = rand.Frand01() * M_2PI; + T phi = ang - m_Side * Floor(ang / Zeps(m_Side)); + T phi2 = phi > m_HalfSide ? phi - m_Side : phi; + T amp = 1 / Zeps(std::cos(phi2)); + T aux = amp * m_BlurOver10 * std::exp(std::log(rad - m_Radius) * m_Exp); + bx = aux * std::cos(ang); + by = aux * std::sin(ang); + } + else + { + bx = 0; + by = 0; + } } helper.Out.x = m_Weight * (helper.In.x + bx); @@ -3675,26 +3718,63 @@ public: string oneovermulsqx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string oneovermulsqy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t bx = 0;\n" - << "\t\treal_t by = 0;\n" - << "\t\treal_t rad = sqrt(Sqr((vIn.x - " << x0 << ") / " << oneovermulsqx << ") + Sqr((vIn.y - " << y0 << ") / " << oneovermulsqy << "));\n" - << "\n" - << "\t\tif (rad > " << radius << ")\n" - << "\t\t{\n" - << "\t\t real_t ang = MwcNext01(mwc) * M_2PI;\n" - << "\t\t real_t phi = ang - " << side << " * floor(ang / Zeps(" << side << "));\n" - << "\n" - << "\t\t if (phi > " << halfside << ")\n" - << "\t\t phi -= " << side << ";\n" - << "\n" - << "\t\t phi = 1 / Zeps(cos(phi));\n" - << "\t\t real_t aux = phi * " << blurover10 << " * exp(log(rad - " << radius << ") * " << exp << ");\n" - << "\t\t bx = aux * cos(ang);\n" - << "\t\t by = aux * sin(ang);\n" - << "\t\t}\n" - << "\n" - << "\t\tvOut.x = " << weight << " * (vIn.x + bx);\n" - << "\t\tvOut.y = " << weight << " * (vIn.y + by);\n" + << "\t\treal_t bx;\n" + << "\t\treal_t by;\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t side = " << side << ";\n" + << "\t\treal_t radius = " << radius << ";\n"; + + if (Compat::m_Compat) + { + ss << "\t\treal_t rad = precalcSqrtSumSquares;\n" + << "\n" + << "\t\tif (rad > radius)\n" + << "\t\t{\n" + << "\t\t real_t ang = MwcNext01(mwc) * M_2PI;\n" + << "\t\t real_t phi = ang - side * floor(ang / Zeps(side));\n" + << "\n" + << "\t\t if (phi > " << halfside << ")\n" + << "\t\t phi -= side;\n" + << "\n" + << "\t\t phi = 1 / Zeps(cos(phi));\n" + << "\t\t real_t aux = phi * " << blurover10 << " * (rad - radius);\n" + << "\t\t bx = aux * cos(ang);\n" + << "\t\t by = aux * sin(ang);\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t bx = 0;\n" + << "\t\t by = 0;\n" + << "\t\t}\n" + << "\n"; + } + else + { + ss << "\t\treal_t rad = sqrt(Sqr(vIn.x - " << x0 << ") * " << oneovermulsqx << " + Sqr(vIn.y - " << y0 << ") * " << oneovermulsqy << ");\n" + << "\n" + << "\t\tif (rad > radius)\n" + << "\t\t{\n" + << "\t\t real_t ang = MwcNext01(mwc) * M_2PI;\n" + << "\t\t real_t phi = ang - side * floor(ang / Zeps(side));\n" + << "\n" + << "\t\t if (phi > " << halfside << ")\n" + << "\t\t phi -= side;\n" + << "\n" + << "\t\t real_t amp = 1 / Zeps(cos(phi));\n" + << "\t\t real_t aux = amp * " << blurover10 << " * exp(log(rad - radius) * " << exp << ");\n" + << "\t\t bx = aux * cos(ang);\n" + << "\t\t by = aux * sin(ang);\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t bx = 0;\n" + << "\t\t by = 0;\n" + << "\t\t}\n" + << "\n"; + } + + ss << "\t\tvOut.x = weight * (vIn.x + bx);\n" + << "\t\tvOut.y = weight * (vIn.y + by);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -3707,11 +3787,15 @@ public: m_BlurOver10 = m_Blur / 10; m_OneOverMulXSq = 1 / Zeps(SQR(m_MulX)); m_OneOverMulYSq = 1 / Zeps(SQR(m_MulY)); + m_NeedPrecalcSumSquares = m_NeedPrecalcSqrtSumSquares = Compat::m_Compat; } virtual vector OpenCLGlobalFuncNames() const override { - return vector { "Zeps", "Sqr" }; + if (Compat::m_Compat) + return vector { "Zeps" }; + else + return vector { "Zeps", "Sqr" }; } protected: @@ -3857,9 +3941,14 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { + T rad; T bx = 0; T by = 0; - T rad = std::sqrt(Sqr((helper.In.x - m_X0) / m_OneOverMulXSq) + Sqr((helper.In.y - m_Y0) / m_OneOverMulYSq)); + + if (Compat::m_Compat) + rad = std::sqrt(Sqr((helper.In.x - m_X0) / Zeps(m_MulX)) + Sqr((helper.In.y - m_Y0) / Zeps(m_MulY))); + else + rad = std::sqrt(Sqr(helper.In.x - m_X0) * m_OneOverMulXSq + Sqr(helper.In.y - m_Y0) * m_OneOverMulYSq); if (rad > m_Radius) { @@ -3896,8 +3985,14 @@ public: ss << "\t{\n" << "\t\treal_t bx = 0;\n" << "\t\treal_t by = 0;\n" - << "\t\treal_t rad = sqrt(Sqr((vIn.x - " << x0 << ") / " << oneovermulsqx << ") + Sqr((vIn.y - " << y0 << ") / " << oneovermulsqy << "));\n" - << "\n" + << "\t\treal_t weight = " << weight << ";\n"; + + if (Compat::m_Compat) + ss << "\t\treal_t rad = sqrt(Sqr((vIn.x - " << x0 << ") / " << mulx << ") + Sqr((vIn.y - " << y0 << ") / " << muly << "); \n"; + else + ss << "\t\treal_t rad = sqrt(Sqr(vIn.x - " << x0 << ") * " << oneovermulsqx << " + Sqr(vIn.y - " << y0 << ") * " << oneovermulsqy << "); \n"; + + ss << "\n" << "\t\tif (rad > " << radius << ")\n" << "\t\t{\n" << "\t\t real_t ang = MwcNext01(mwc) * M_2PI;\n" @@ -3907,15 +4002,15 @@ public: << "\t\t by = aux * sin(ang);\n" << "\t\t}\n" << "\n" - << "\t\tvOut.x = " << weight << " * (vIn.x + bx);\n" - << "\t\tvOut.y = " << weight << " * (vIn.y + by);\n" + << "\t\tvOut.x = weight * (vIn.x + bx);\n" + << "\t\tvOut.y = weight * (vIn.y + by);\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } - virtual void Precalc() override { + m_Power = std::max(T(0), m_Power); m_BlurOver10 = m_Blur / 10; m_OneOverMulXSq = 1 / Zeps(SQR(m_MulX)); m_OneOverMulYSq = 1 / Zeps(SQR(m_MulY)); @@ -3943,7 +4038,6 @@ protected: m_Params.push_back(ParamWithName(true, &m_OneOverMulXSq, prefix + "depth_sine2_one_over_mulx_sq")); m_Params.push_back(ParamWithName(true, &m_OneOverMulYSq, prefix + "depth_sine2_one_over_muly_sq")); } - private: T m_Power; T m_Blur; @@ -4138,7 +4232,11 @@ public: } else { - xx = x0 * m_CosAlpha - y0 * m_SinAlpha; + if (Compat::m_Compat) + xx = x0 * m_CosAlpha - y0 * m_SinAlpha; + else + xx = x0 * m_CosAlpha + y0 * m_SinAlpha; + yy = x0 * m_SinAlpha + y0 * m_CosAlpha; T nx = xx / std::sqrt(1 - SQR(yy)) * (1 - std::sqrt(1 - Sqr(-std::abs(yy) + 1))); xx = nx * m_CosAlpha + yy * m_SinAlpha; @@ -4161,8 +4259,11 @@ public: string sina = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cosa = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t x0 = " << weight << " * vIn.x;\n" - << "\t\treal_t y0 = " << weight << " * vIn.y;\n" + << "\t\treal_t weight = " << weight << ";\n" + << "\t\treal_t cosa = " << cosa << ";\n" + << "\t\treal_t sina = " << sina << ";\n" + << "\t\treal_t x0 = weight * vIn.x;\n" + << "\t\treal_t y0 = weight * vIn.y;\n" << "\t\treal_t xx = x0;\n" << "\t\treal_t yy = y0;\n" << "\t\treal_t r = SQR(xx) + SQR(yy);\n" @@ -4183,12 +4284,17 @@ public: << "\t\t vOut.y = y0;\n" << "\t\t}\n" << "\t\telse\n" - << "\t\t{\n" - << "\t\t xx = x0 * " << cosa << " - y0 * " << sina << ";\n" - << "\t\t yy = x0 * " << sina << " + y0 * " << cosa << ";\n" + << "\t\t{\n"; + + if (Compat::m_Compat) + ss << "\t\t xx = x0 * cosa - y0 * sina;\n"; + else + ss << "\t\t xx = x0 * cosa + y0 * sina;\n"; + + ss << "\t\t yy = x0 * sina + y0 * cosa;\n" << "\t\t real_t nx = xx / sqrt(1 - SQR(yy)) * (1 - sqrt(1 - Sqr(-fabs(yy) + 1)));\n" - << "\t\t xx = nx * " << cosa << " + yy * " << sina << ";\n" - << "\t\t yy = -nx * " << sina << " + yy * " << cosa << ";\n" + << "\t\t xx = nx * cosa + yy * sina;\n" + << "\t\t yy = -nx * sina + yy * cosa;\n" << "\t\t vOut.x = xx;\n" << "\t\t vOut.y = yy;\n" << "\t\t}\n" @@ -4367,7 +4473,7 @@ protected: string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_LengthScalar, prefix + "excinis_lengthscalar", 1)); - m_Params.push_back(ParamWithName(&m_RadiusFunc, prefix + "excinis_radiusFunc", 0, eParamType::INTEGER, 0, 5)); + m_Params.push_back(ParamWithName(&m_RadiusFunc, prefix + "excinis_radiusFunc", 0, eParamType::REAL, 0, 5)); m_Params.push_back(ParamWithName(&m_Eps, prefix + "excinis_eps", T(0.1))); } @@ -4675,16 +4781,16 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Dir, prefix + "vibration2_dir", 0, eParamType::REAL_CYCLIC, 0, M_2PI)); - m_Params.push_back(ParamWithName(&m_Angle, prefix + "vibration2_angle", T(M_PI_2), eParamType::REAL_CYCLIC, 0, M_2PI)); + m_Params.push_back(ParamWithName(&m_Dir, prefix + "vibration2_dir", 0)); + m_Params.push_back(ParamWithName(&m_Angle, prefix + "vibration2_angle", T(M_PI_2))); m_Params.push_back(ParamWithName(&m_Freq, prefix + "vibration2_freq", 1)); m_Params.push_back(ParamWithName(&m_Amp, prefix + "vibration2_amp", T(0.25))); - m_Params.push_back(ParamWithName(&m_Phase, prefix + "vibration2_phase", 0, eParamType::REAL_CYCLIC, 0, 1)); - m_Params.push_back(ParamWithName(&m_Dir2, prefix + "vibration2_dir2", T(M_PI_2), eParamType::REAL_CYCLIC, 0, M_2PI)); - m_Params.push_back(ParamWithName(&m_Angle2, prefix + "vibration2_angle2", T(M_PI_2), eParamType::REAL_CYCLIC, 0, M_2PI)); + m_Params.push_back(ParamWithName(&m_Phase, prefix + "vibration2_phase", 0)); + m_Params.push_back(ParamWithName(&m_Dir2, prefix + "vibration2_dir2", T(M_PI_2))); + m_Params.push_back(ParamWithName(&m_Angle2, prefix + "vibration2_angle2", T(M_PI_2))); m_Params.push_back(ParamWithName(&m_Freq2, prefix + "vibration2_freq2", 1)); m_Params.push_back(ParamWithName(&m_Amp2, prefix + "vibration2_amp2", T(0.25))); - m_Params.push_back(ParamWithName(&m_Phase2, prefix + "vibration2_phase2", 0, eParamType::REAL_CYCLIC, 0, 1)); + m_Params.push_back(ParamWithName(&m_Phase2, prefix + "vibration2_phase2", 0)); m_Params.push_back(ParamWithName(&m_Dm, prefix + "vibration2_dm")); m_Params.push_back(ParamWithName(&m_Dmfreq, prefix + "vibration2_dmfreq")); m_Params.push_back(ParamWithName(&m_Tm , prefix + "vibration2_tm")); @@ -4738,7 +4844,7 @@ private: T m_F2mfreq; T m_A2m; T m_A2mfreq; - T m_CosDir; + T m_CosDir;//Precalc. T m_SinDir; T m_ScaledFreq; T m_PhaseShift; @@ -5205,6 +5311,11 @@ public: helper.Out.x = (std::cos(final_angle) * R + xfinal) * m_Weight; helper.Out.y = (std::sin(final_angle) * R + yfinal) * m_Weight; } + else + { + helper.Out.x = 0; + helper.Out.y = 0; + } helper.Out.z = DefaultZ(helper); } @@ -5224,6 +5335,8 @@ public: string seed = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sizeover2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t seed = " << seed << ";\n" + << "\t\treal_t weight = " << weight << ";\n" << "\t\treal_t k = MwcNext01(mwc) * 6;\n" << "\t\tint int_angle = (int)floor(k);\n" << "\t\treal_t x = k - int_angle;\n" @@ -5234,16 +5347,22 @@ public: << "\t\treal_t Y = (floor(MwcNext01(mwc) * " << y << " * 2) - " << y << ");\n" << "\t\treal_t xfinal = fma(0.5, Y, X);\n" << "\t\treal_t yfinal = Y * 0.86602540378443864676372317075294;\n" - << "\t\treal_t N = HashShadertoy(yfinal, xfinal, " << seed << ");\n" + << "\t\treal_t N = HashShadertoy(yfinal, xfinal, seed);\n" << "\n" << "\t\tif (N < " << density << ")\n" << "\t\t{\n" << "\t\t real_t z_scaled = z * sqrt(MwcNext01(mwc)) * 1.1547005383792515290182975610039;\n" - << "\t\t real_t n = HashShadertoy(xfinal, yfinal, " << seed << ");\n" + << "\t\t real_t n = HashShadertoy(xfinal, yfinal, seed);\n" << "\t\t real_t R = " << sizeover2 << " * z_scaled * pow(n, " << power << ");\n" - << "\t\t vOut.x = fma(cos(final_angle), R, xfinal) * " << weight << ";\n" - << "\t\t vOut.y = fma(sin(final_angle), R, yfinal) * " << weight << ";\n" + << "\t\t vOut.x = fma(cos(final_angle), R, xfinal) * weight;\n" + << "\t\t vOut.y = fma(sin(final_angle), R, yfinal) * weight;\n" << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t vOut.x = (real_t)(0.0);\n" + << "\t\t vOut.y = (real_t)(0.0);\n" + << "\t\t}\n" + << "\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -5429,6 +5548,7 @@ public: virtual void Precalc() override { + m_Power = std::max(m_Power, T(2)); m_Alpha = T(M_2PI) / m_Power; m_AlphaCoeff = std::tan(m_Alpha * T(0.5)) * 2; m_RoundCoeff = m_Roundstr / std::sin(m_Alpha * T(0.5)) / m_Power * 2; @@ -5444,7 +5564,7 @@ protected: m_Params.push_back(ParamWithName(&m_Roundstr, prefix + "smartshape_roundstr")); m_Params.push_back(ParamWithName(&m_Roundwidth, prefix + "smartshape_roundwidth", 1)); m_Params.push_back(ParamWithName(&m_Distortion, prefix + "smartshape_distortion", 1)); - m_Params.push_back(ParamWithName(&m_Compensation, prefix + "smartshape_compensation", 0, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Compensation, prefix + "smartshape_compensation", 0, eParamType::REAL, 0, 1)); m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "smartshape_alpha"));//Precalc. m_Params.push_back(ParamWithName(true, &m_AlphaCoeff, prefix + "smartshape_alphacoeff")); m_Params.push_back(ParamWithName(true, &m_RoundCoeff, prefix + "smartshape_roundcoeff")); @@ -5588,8 +5708,8 @@ protected: string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_CellSize, prefix + "squares_cellsize")); - m_Params.push_back(ParamWithName(&m_Min, prefix + "squares_min", 0, eParamType::INTEGER, 0)); - m_Params.push_back(ParamWithName(&m_Max, prefix + "squares_max", 10, eParamType::INTEGER, 0)); + m_Params.push_back(ParamWithName(&m_Min, prefix + "squares_min", 0, eParamType::REAL, 0)); + m_Params.push_back(ParamWithName(&m_Max, prefix + "squares_max", 10, eParamType::REAL, 0)); m_Params.push_back(ParamWithName(&m_Num, prefix + "squares_num", 10)); m_Params.push_back(ParamWithName(&m_Seed, prefix + "squares_seed", 1)); m_Params.push_back(ParamWithName(&m_Zero, prefix + "squares_zero", T(0.5))); @@ -5628,28 +5748,28 @@ public: T f = k - int_angle; T ff; - if (m_Stripes > 0) + if (m_StripesAbs > 0) { - T fs = std::trunc(f * m_Stripes); + T fs = std::trunc(f * m_StripesAbs); T dif; if (std::fmod(int_angle, T(2)) == 0) - dif = m_Width * (f * m_Stripes - fs); + dif = m_Width * (f * m_StripesAbs - fs); else - dif = 1 - m_Width * (f * m_Stripes - fs); + dif = 1 - m_Width * (f * m_StripesAbs - fs); - ff = (dif + fs) / m_Stripes; + ff = (dif + fs) / m_StripesAbs; } else ff = f; T x = ff * m_Length; - T z = Zeps(std::sqrt(1 + x * x - x * m_CosAlpha)); + T z = Zeps(std::sqrt(1 + x * x - x * m_CosAlpha2)); T angle_sign = (int_angle - Floor(k / 2) * 2) == 1 ? T(1) : T(-1); - T final_angle = m_TwopiPower * int_angle + angle_sign * std::asin(m_SinAlpha * x / z) - T(M_PI_2); - T z_scaled = z * std::sqrt(rand.Frand01() * m_OnemHoleSq + m_HoleSq); - helper.Out.x = std::cos(final_angle) * z_scaled * m_Weight; - helper.Out.y = std::sin(final_angle) * z_scaled * m_Weight; + T final_angle = m_TwopiPower * (int_angle / 2) + angle_sign * std::asin(m_SinAlpha * x / z) - T(M_PI_2); + T z_scaled = m_Weight * (z * std::sqrt(rand.Frand01() * m_OnemHoleSq + m_HoleSq)); + helper.Out.x = std::cos(final_angle) * z_scaled; + helper.Out.y = std::sin(final_angle) * z_scaled; helper.Out.z = DefaultZ(helper); } @@ -5672,35 +5792,37 @@ public: string twopipower = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sinalpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index; - string cosalpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string cosalpha2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string stripesabs = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t k = MwcNext01(mwc) * " << power2 << ";\n" - << "\t\treal_t int_angle = floor(k);\n" + << "\t\tint int_angle = (int)floor(k);\n" << "\t\treal_t f = k - int_angle;\n" + << "\t\treal_t stripes = " << stripesabs << ";\n" << "\t\treal_t ff;\n" << "\n" - << "\t\tif (" << stripes << " > 0.0)\n" + << "\t\tif (stripes > (real_t)(0.0))\n" << "\t\t{\n" - << "\t\t real_t fs = trunc(f * " << stripes << ");\n" + << "\t\t real_t fs = trunc(f * stripes);\n" << "\t\t real_t dif;\n" << "\n" - << "\t\t if (fmod(int_angle, 2.0) == 0)\n" - << "\t\t dif = " << width << " * fma(f, " << stripes << ", -fs);\n" + << "\t\t if (fmod(int_angle, (real_t)(2.0)) == 0)\n" + << "\t\t dif = " << width << " * fma(f, stripes, -fs);\n" << "\t\t else\n" - << "\t\t dif = 1 - " << width << " * fma(f, " << stripes << ", -fs);\n" + << "\t\t dif = 1 - " << width << " * fma(f, stripes, -fs);\n" << "\n" - << "\t\t ff = (dif + fs) / " << stripes << ";\n" + << "\t\t ff = (dif + fs) / stripes;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t ff = f;\n" << "\n" << "\t\treal_t x = ff * " << length << ";\n" - << "\t\treal_t z = Zeps(sqrt(1 + x * x - x * " << cosalpha << "));\n" - << "\t\treal_t angle_sign = (int_angle - floor(k/2) * 2) == 1.0 ? 1.0 : -1.0;\n" - << "\t\treal_t final_angle = " << twopipower << " * int_angle + angle_sign * asin(" << sinalpha << " * x / z) - MPI2;\n" - << "\t\treal_t z_scaled = z * sqrt(fma(MwcNext01(mwc), " << onemholesq << ", " << holesq << "));\n" - << "\t\tvOut.x = cos(final_angle) * z_scaled * " << weight << ";\n" - << "\t\tvOut.y = sin(final_angle) * z_scaled * " << weight << ";\n" + << "\t\treal_t z = Zeps(sqrt(1 + x * x - x * " << cosalpha2 << "));\n" + << "\t\treal_t angle_sign = (int_angle - floor(k/2) * 2) == (real_t)(1.0) ? (real_t)(1.0) : (real_t)(-1.0);\n" + << "\t\treal_t final_angle = " << twopipower << " * (int_angle / 2) + angle_sign * asin(" << sinalpha << " * x / z) - MPI2;\n" + << "\t\treal_t z_scaled = " << weight << " * (z * sqrt(fma(MwcNext01(mwc), " << onemholesq << ", " << holesq << ")));\n" + << "\t\tvOut.x = cos(final_angle) * z_scaled;\n" + << "\t\tvOut.y = sin(final_angle) * z_scaled;\n" << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); @@ -5708,15 +5830,18 @@ public: virtual void Precalc() override { - T alpha = T(M_PI) / m_Power; + T p = Zeps(m_Power); + T alpha = T(M_PI) / p; m_Length = std::sqrt(1 + m_Range * m_Range - 2 * m_Range * std::cos(alpha)); m_Alpha = std::asin(std::sin(alpha) * m_Range / Zeps(m_Length)); - m_HoleSq = SQR(m_Hole); + T holeAbs = std::min(std::abs(m_Hole), T(1)); + m_StripesAbs = Zeps(std::abs(m_Stripes)); + m_HoleSq = SQR(holeAbs); m_OnemHoleSq = 1 - m_HoleSq; - m_TwopiPower = (M_2PI / m_Power) * T(0.5); + m_TwopiPower = (M_2PI / p); m_Power2 = m_Power * 2; m_SinAlpha = std::sin(m_Alpha); - m_CosAlpha = std::cos(m_Alpha) * 2; + m_CosAlpha2 = std::cos(m_Alpha) * 2; } virtual vector OpenCLGlobalFuncNames() const override @@ -5731,8 +5856,8 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Power, prefix + "starblur2_power", 5)); m_Params.push_back(ParamWithName(&m_Range, prefix + "starblur2_range", T(0.40162283177245455973959534526548))); - m_Params.push_back(ParamWithName(&m_Hole, prefix + "starblur2_hole", T(0.5), eParamType::REAL, 0, 1)); - m_Params.push_back(ParamWithName(&m_Stripes, prefix + "starblur2_stripes", 5, eParamType::REAL, 0)); + m_Params.push_back(ParamWithName(&m_Hole, prefix + "starblur2_hole", T(0.5))); + m_Params.push_back(ParamWithName(&m_Stripes, prefix + "starblur2_stripes", 5)); m_Params.push_back(ParamWithName(&m_Width, prefix + "starblur2_width", T(0.2))); m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "starblur2_alpha"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Length, prefix + "starblur2_length")); @@ -5741,7 +5866,8 @@ protected: m_Params.push_back(ParamWithName(true, &m_TwopiPower, prefix + "starblur2_twopi_power")); m_Params.push_back(ParamWithName(true, &m_Power2, prefix + "starblur2_power2")); m_Params.push_back(ParamWithName(true, &m_SinAlpha, prefix + "starblur2_sin_alpha")); - m_Params.push_back(ParamWithName(true, &m_CosAlpha, prefix + "starblur2_cos_alpha")); + m_Params.push_back(ParamWithName(true, &m_CosAlpha2, prefix + "starblur2_cos_alpha2")); + m_Params.push_back(ParamWithName(true, &m_StripesAbs, prefix + "starblur2_stripes_abs")); } private: @@ -5757,7 +5883,8 @@ private: T m_TwopiPower; T m_Power2; T m_SinAlpha; - T m_CosAlpha; + T m_CosAlpha2; + T m_StripesAbs; }; /// @@ -5801,7 +5928,7 @@ public: else scalar_xy = v2T(std::atan2(helper.In.x, helper.In.y), std::atan2(helper.In.y, helper.In.x)); - factor = tmp_vec + v2T(m_SinXAmp * std::sin(scalar_xy.x * m_SinXFreqPi), m_SinYAmp * std::sin(scalar_xy.y * m_SinYFreqPi));; + factor = tmp_vec + v2T(m_SinXAmp * std::sin(scalar_xy.x * m_SinXFreqPi), m_SinYAmp * std::sin(scalar_xy.y * m_SinYFreqPi)); } helper.Out.x = factor.x * (helper.In.x - helper.In.y) * (helper.In.x + m_MultY * helper.In.y) * r; @@ -5827,6 +5954,7 @@ public: string sinxfreqpi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sinyfreqpi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" + << "\t\treal_t mode = " << mode << ";\n" << "\t\treal_t r = " << weight << " / Zeps(sqrt((SQR(vIn.y) * " << multy << ") + (" << multx << " * SQR(vIn.x))));\n" << "\t\treal2 factor;\n" << "\n" @@ -5840,13 +5968,13 @@ public: << "\t\t real2 tmp_vec = (real2)(1, 2);\n" << "\t\t real2 scalar_xy;\n" << "\n" - << "\t\t if (" << mode << " <= 0)\n" + << "\t\t if (mode <= 0)\n" << "\t\t scalar_xy = (real2)(vIn.x, vIn.y);\n" - << "\t\t else if (" << mode << " <= 1)\n" + << "\t\t else if (mode <= 1)\n" << "\t\t scalar_xy = (real2)(exp(-vIn.x), exp(-vIn.y));\n" - << "\t\t else if (" << mode << " <= 2)\n" + << "\t\t else if (mode <= 2)\n" << "\t\t scalar_xy = (real2)(1 / Zeps(vIn.x), 1 / Zeps(vIn.y));\n" - << "\t\t else if (" << mode << " <= 3)\n" + << "\t\t else if (mode <= 3)\n" << "\t\t scalar_xy = (real2)(log(fabs(vIn.x)), " << sinyamp << " * log(fabs(vIn.y)));\n" << "\t\t else\n" << "\t\t scalar_xy = (real2)(atan2(vIn.x, vIn.y), atan2(vIn.y, vIn.x));\n" @@ -5883,7 +6011,7 @@ protected: m_Params.push_back(ParamWithName(&m_SinXFreq, prefix + "unicorngaloshen_sin_x_freq", T(0.1))); m_Params.push_back(ParamWithName(&m_SinYAmp, prefix + "unicorngaloshen_sin_y_amplitude", 2)); m_Params.push_back(ParamWithName(&m_SinYFreq, prefix + "unicorngaloshen_sin_y_freq", T(0.2))); - m_Params.push_back(ParamWithName(&m_Mode, prefix + "unicorngaloshen_mode", 0, eParamType::INTEGER, 0, 4)); + m_Params.push_back(ParamWithName(&m_Mode, prefix + "unicorngaloshen_mode", 0, eParamType::REAL, 0, 4)); m_Params.push_back(ParamWithName(true, &m_SinXFreqPi, prefix + "unicorngaloshen_sin_x_freq_pi"));//Precalc. m_Params.push_back(ParamWithName(true, &m_SinYFreqPi, prefix + "unicorngaloshen_sin_y_freq_pi")); } @@ -6138,9 +6266,9 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_C1, prefix + "dragonfire_c1", T(0.5))); m_Params.push_back(ParamWithName(&m_C2, prefix + "dragonfire_c2", T(0.25))); - m_Params.push_back(ParamWithName(&m_FuzzyMode, prefix + "dragonfire_fuzzyMode", 0, eParamType::INTEGER, 0, 7)); + m_Params.push_back(ParamWithName(&m_FuzzyMode, prefix + "dragonfire_fuzzyMode", 0, eParamType::REAL, 0, 7)); m_Params.push_back(ParamWithName(&m_FuzzyRadius, prefix + "dragonfire_fuzzyRadius", 1)); - m_Params.push_back(ParamWithName(&m_FuzzyInterpolationMode, prefix + "dragonfire_fuzzyInterpolationMode", 0, eParamType::INTEGER, 0, 6)); + m_Params.push_back(ParamWithName(&m_FuzzyInterpolationMode, prefix + "dragonfire_fuzzyInterpolationMode", 0, eParamType::REAL, 0, 6)); m_Params.push_back(ParamWithName(&m_FuzzyInterpolationPosition, prefix + "dragonfire_fuzzyInterpolationPosition", 1)); m_Params.push_back(ParamWithName(&m_LogScalarFuzzy, prefix + "dragonfire_logScalarFuzzy", M_2PI)); m_Params.push_back(ParamWithName(&m_AdjustedFuzzyScalar, prefix + "dragonfire_adjustedFuzzyScalar", T(0.5))); @@ -6206,15 +6334,26 @@ public: } v2T R; - T xval1 = tiletype < 1 ? x : x - 1; - T xval2 = tiletype < 1 ? x - 1 : x; + T xval1, xval2; + + if (tiletype < 1) + { + xval1 = x; + xval2 = x - 1; + } + else + { + xval1 = x - 1; + xval2 = x; + } + R = v2T(std::pow(std::pow(std::abs(xval1), m_N) + std::pow(std::abs(y), m_N), m_OneN), std::pow(std::pow(std::abs(xval2), m_N) + std::pow(std::abs(y - 1), m_N), m_OneN)); T r00 = std::abs(R.x - T(0.5)) / m_Rmax; T r11 = std::abs(R.y - T(0.5)) / m_Rmax; v2T xy; if (r00 < 1) - xy = v2T(x + Floor(helper.In.x) * 2, y + Floor(helper.In.y) * 2); + xy = v2T((x + Floor(helper.In.x)) * 2, (y + Floor(helper.In.y)) * 2); else xy = v2T(0, 0); @@ -6231,8 +6370,8 @@ public: { if (r11 < 1) { - helper.Out.x = xy.x + (x + Floor(helper.In.x) * 2) - helper.In.x; - helper.Out.y = xy.y + (y + Floor(helper.In.y) * 2) - helper.In.y; + helper.Out.x = xy.x + ((x + Floor(helper.In.x)) * 2) - helper.In.x; + helper.Out.y = xy.y + ((y + Floor(helper.In.y)) * 2) - helper.In.y; } else { @@ -6269,8 +6408,15 @@ public: string rads = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string halfampmax = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t x1 = vIn.x * " << scale << ";\n" - << "\t\treal_t y1 = vIn.y * " << scale << ";\n" + << "\t\treal_t scale = " << scale << ";\n" + << "\t\treal_t seed = " << seed << ";\n" + << "\t\treal_t rmax = " << rmax << ";\n" + << "\t\treal_t onen = " << onen << ";\n" + << "\t\treal_t amp = " << amp << ";\n" + << "\t\treal_t rads = " << rads << ";\n" + << "\t\treal_t n = " << n << ";\n" + << "\t\treal_t x1 = vIn.x * scale;\n" + << "\t\treal_t y1 = vIn.y * scale;\n" << "\t\treal_t intx = floor(x1 + 0.5);\n" << "\t\treal_t inty = floor(y1 + 0.5);\n" << "\t\treal_t r_x = x1 - intx;\n" @@ -6279,39 +6425,50 @@ public: << "\t\treal_t y = r_y < 0 ? 1 + r_y : r_y;\n" << "\t\treal_t tiletype;\n" << "\n" - << "\t\tif (" << seed << " == 0)\n" + << "\t\tif (seed == 0)\n" << "\t\t{\n" << "\t\t tiletype = 0;\n" << "\t\t}\n" - << "\t\telse if (" << seed << " == 1)\n" + << "\t\telse if (seed == 1)\n" << "\t\t{\n" << "\t\t tiletype = 1;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" - << "\t\t real_t xrand = floor(fabs(vIn.x) + 0.5);\n" - << "\t\t real_t yrand = floor(fabs(vIn.y) + 0.5);\n" - << "\t\t real_t randint0 = HashShadertoy(xrand, yrand, " << seed << ");\n" + << "\t\t real_t xrand = floor(fabs(vIn.x) + (real_t)0.5);\n" + << "\t\t real_t yrand = floor(fabs(vIn.y) + (real_t)0.5);\n" + << "\t\t real_t randint0 = HashShadertoy(xrand, yrand, seed);\n" << "\t\t real_t randint = fmod(fma(randint0, (real_t)(32747.0), (real_t)(12345.0)), (real_t)(65535.0));\n" - << "\t\t tiletype = fmod(randint, 2.0);\n" + << "\t\t tiletype = fmod(randint, (real_t)2.0);\n" << "\t\t}\n" << "\n" - << "\t\treal_t xval1 = tiletype < 1 ? x : x - 1;\n" - << "\t\treal_t xval2 = tiletype < 1 ? x - 1 : x;\n" - << "\t\treal2 R = (real2)(pow(pow(fabs(xval1), " << n << ") + pow(fabs(y), " << n << "), " << onen << "), pow(pow(fabs(xval2), " << n << ") + pow(fabs(y - 1), " << n << "), " << onen << "));\n" - << "\t\treal_t r00 = fabs(R.x - (real_t)(0.5)) / " << rmax << ";\n" - << "\t\treal_t r11 = fabs(R.y - (real_t)(0.5)) / " << rmax << ";\n" + << "\t\treal_t xval1, xval2;\n" + << "\n" + << "\t\tif (tiletype < 1)\n" + << "\t\t{\n" + << "\t\t xval1 = x;\n" + << "\t\t xval2 = x - 1;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t xval1 = x - 1;\n" + << "\t\t xval2 = x;\n" + << "\t\t}\n" + << "\n" + << "\t\treal2 R = (real2)(pow(pow(fabs(xval1), n) + pow(fabs(y), n), onen), pow(pow(fabs(xval2), n) + pow(fabs(y - 1), n), onen));\n" + << "\t\treal_t r00 = fabs(R.x - (real_t)(0.5)) / rmax;\n" + << "\t\treal_t r11 = fabs(R.y - (real_t)(0.5)) / rmax;\n" << "\t\treal2 xy;\n" << "\n" << "\t\tif (r00 < 1)\n" - << "\t\t xy = (real2)(fma(floor(vIn.x), (real_t)(2.0), x), fma(floor(vIn.y), (real_t)(2.0), y));\n" + << "\t\t xy = (real2)((floor(vIn.x) + x) * (real_t)(2.0), (floor(vIn.y) + y) * (real_t)(2.0));\n" << "\t\telse\n" << "\t\t xy = (real2)(0.0, 0.0);\n" << "\n" - << "\t\treal_t cost = cos(" << rads << ");\n" - << "\t\treal_t sint = sin(" << rads << ");\n" - << "\t\treal_t roundx = (floor(vIn.x / " << amp << ") + (real_t)(0.5)) * " << amp << ";\n" - << "\t\treal_t roundy = (floor(vIn.y / " << amp << ") + (real_t)(0.5)) * " << amp << ";\n" + << "\t\treal_t cost = cos(rads);\n" + << "\t\treal_t sint = sin(rads);\n" + << "\t\treal_t roundx = (floor(vIn.x / amp) + (real_t)(0.5)) * amp;\n" + << "\t\treal_t roundy = (floor(vIn.y / amp) + (real_t)(0.5)) * amp;\n" << "\t\treal_t vx = vIn.x - roundx;\n" << "\t\treal_t vy = vIn.y - roundy;\n" << "\t\treal_t newx = fma(cost, vx, sint * vy);\n" @@ -6321,8 +6478,8 @@ public: << "\t\t{\n" << "\t\t if (r11 < 1)\n" << "\t\t {\n" - << "\t\t vOut.x = xy.x + fma(floor(vIn.x), (real_t)(2.0), x) - vIn.x;\n" - << "\t\t vOut.y = xy.y + fma(floor(vIn.y), (real_t)(2.0), y) - vIn.y;\n" + << "\t\t vOut.x = xy.x + ((floor(vIn.x) + x) * (real_t)(2.0)) - vIn.x;\n" + << "\t\t vOut.y = xy.y + ((floor(vIn.y) + y) * (real_t)(2.0)) - vIn.y;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" @@ -6436,8 +6593,19 @@ public: tiletype = fmod(randint, T(2)); } - T xval1 = tiletype < 1 ? x : x - 1; - T xval2 = tiletype < 1 ? x - 1 : x; + T xval1, xval2; + + if (tiletype < 1) + { + xval1 = x; + xval2 = x - 1; + } + else + { + xval1 = x - 1; + xval2 = x; + } + v2T R(std::pow(std::pow(std::abs(xval1), m_N) + std::pow(std::abs(y), m_N), m_OneN), std::pow(std::pow(std::abs(xval2), m_N) + std::pow(std::abs(y - 1), m_N), m_OneN)); T r00 = std::abs(R.x - T(0.5)) / m_Rmax; T r11 = std::abs(R.y - T(0.5)) / m_Rmax; @@ -6475,8 +6643,15 @@ public: string seed2half = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t x1 = vIn.x * " << scale << ";\n" - << "\t\treal_t y1 = vIn.y * " << scale << ";\n" + << "\t\treal_t scale = " << scale << ";\n" + << "\t\treal_t seed = " << seed << ";\n" + << "\t\treal_t seed2 = " << seed2 << ";\n" + << "\t\treal_t rmax = " << rmax << ";\n" + << "\t\treal_t onen = " << onen << ";\n" + << "\t\treal_t n = " << n << ";\n" + << "\t\treal_t size = " << size << ";\n" + << "\t\treal_t x1 = vIn.x * scale;\n" + << "\t\treal_t y1 = vIn.y * scale;\n" << "\t\treal_t intx = floor(x1 + 0.5);\n" << "\t\treal_t inty = floor(y1 + 0.5);\n" << "\t\treal_t r_x = x1 - intx;\n" @@ -6485,34 +6660,45 @@ public: << "\t\treal_t y = r_y < 0 ? 1 + r_y : r_y;\n" << "\t\treal_t tiletype;\n" << "\n" - << "\t\tif (" << seed << " == 0)\n" + << "\t\tif (seed == 0)\n" << "\t\t{\n" << "\t\t tiletype = 0;\n" << "\t\t}\n" - << "\t\telse if (" << seed << " == 1)\n" + << "\t\telse if (seed == 1)\n" << "\t\t{\n" << "\t\t tiletype = 1;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" - << "\t\t real_t xrand = floor(vIn.x + 0.5) * " << seed2 << ";\n" - << "\t\t real_t yrand = floor(vIn.y + 0.5) * " << seed2 << ";\n" + << "\t\t real_t xrand = floor(vIn.x + 0.5) * seed2;\n" + << "\t\t real_t yrand = floor(vIn.y + 0.5) * seed2;\n" << "\t\t real_t niter = xrand + yrand + xrand * yrand;\n" - << "\t\t real_t randint0 = (niter + " << seed << ") * " << seed2half << ";\n" + << "\t\t real_t randint0 = (niter + seed) * " << seed2half << ";\n" << "\t\t real_t randint = fmod(fma(randint0, (real_t)(32747.0), (real_t)(12345.0)), (real_t)(65535.0));\n" << "\t\t tiletype = fmod(randint, 2.0);\n" << "\t\t}\n" << "\n" - << "\t\treal_t xval1 = tiletype < 1 ? x : x - 1;\n" - << "\t\treal_t xval2 = tiletype < 1 ? x - 1 : x;\n" - << "\t\treal2 R = (real2)(pow(pow(fabs(xval1), " << n << ") + pow(fabs(y), " << n << "), " << onen << "), pow(pow(fabs(xval2), " << n << ") + pow(fabs(y - 1), " << n << "), " << onen << "));\n" - << "\t\treal_t r00 = fabs(R.x - 0.5) / " << rmax << ";\n" - << "\t\treal_t r11 = fabs(R.y - 0.5) / " << rmax << ";\n" + << "\t\treal_t xval1, xval2;\n" + << "\n" + << "\t\tif (tiletype < 1)\n" + << "\t\t{\n" + << "\t\t xval1 = x;\n" + << "\t\t xval2 = x - 1;\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t xval1 = x - 1;\n" + << "\t\t xval2 = x;\n" + << "\t\t}\n" + << "\n" + << "\t\treal2 R = (real2)(pow(pow(fabs(xval1), n) + pow(fabs(y), n), onen), pow(pow(fabs(xval2), n) + pow(fabs(y - 1), n), onen));\n" + << "\t\treal_t r00 = fabs(R.x - (real_t)0.5) / rmax;\n" + << "\t\treal_t r11 = fabs(R.y - (real_t)0.5) / rmax;\n" << "\n" << "\t\tif (r00 > 1 && r11 > 1)\n" << "\t\t{\n" - << "\t\t vOut.x = (x + floor(vIn.x)) * " << size << ";\n" - << "\t\t vOut.y = (y + floor(vIn.y)) * " << size << ";\n" + << "\t\t vOut.x = (x + floor(vIn.x)) * size;\n" + << "\t\t vOut.y = (y + floor(vIn.y)) * size;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" @@ -7165,10 +7351,10 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Scalex, prefix + "waves3_scalex", T(0.05))); m_Params.push_back(ParamWithName(&m_Scaley, prefix + "waves3_scaley", T(0.05))); - m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves3_freqx", T(7.0))); - m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves3_freqy", T(13.0))); + m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves3_freqx", 7)); + m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves3_freqy", 13)); m_Params.push_back(ParamWithName(&m_Sxfreq, prefix + "waves3_sx_freq")); - m_Params.push_back(ParamWithName(&m_Syfreq, prefix + "waves3_sy_freq", T(2.0))); + m_Params.push_back(ParamWithName(&m_Syfreq, prefix + "waves3_sy_freq", 2)); m_Params.push_back(ParamWithName(true, &m_HalfScalex, prefix + "waves3_half_scalex"));//Precalc. m_Params.push_back(ParamWithName(true, &m_HalfScaley, prefix + "waves3_half_scaley")); } @@ -7252,9 +7438,9 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Scalex, prefix + "waves4_scalex", T(0.05))); m_Params.push_back(ParamWithName(&m_Scaley, prefix + "waves4_scaley", T(0.05))); - m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves4_freqx", T(7.0))); - m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves4_freqy", T(13.0))); - m_Params.push_back(ParamWithName(&m_Cont, prefix + "waves4_cont", T(0), eParamType::INTEGER, T(0), T(1))); + m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves4_freqx", 7)); + m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves4_freqy", 13)); + m_Params.push_back(ParamWithName(&m_Cont, prefix + "waves4_cont", 0, eParamType::INTEGER, 0, 1)); m_Params.push_back(ParamWithName(&m_Yfact, prefix + "waves4_yfact", T(0.1))); m_Params.push_back(ParamWithName(true, &m_Yfact001, prefix + "waves4_yfact001"));//Precalc. } @@ -7367,12 +7553,12 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Scalex, prefix + "waves22_scalex", T(0.05))); m_Params.push_back(ParamWithName(&m_Scaley, prefix + "waves22_scaley", T(0.05))); - m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves22_freqx", T(7.0))); - m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves22_freqy", T(13.0))); - m_Params.push_back(ParamWithName(&m_Modex, prefix + "waves22_modex", T(0), eParamType::INTEGER, T(0), T(1))); - m_Params.push_back(ParamWithName(&m_Modey, prefix + "waves22_modey", T(0), eParamType::INTEGER, T(0), T(1))); - m_Params.push_back(ParamWithName(&m_Powerx, prefix + "waves22_powerx", T(2.0))); - m_Params.push_back(ParamWithName(&m_Powery, prefix + "waves22_powery", T(2.0))); + m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves22_freqx", 7)); + m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves22_freqy", 13)); + m_Params.push_back(ParamWithName(&m_Modex, prefix + "waves22_modex", 0, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Modey, prefix + "waves22_modey", 0, eParamType::INTEGER, 0, 1)); + m_Params.push_back(ParamWithName(&m_Powerx, prefix + "waves22_powerx", 2)); + m_Params.push_back(ParamWithName(&m_Powery, prefix + "waves22_powery", 2)); } private: @@ -7459,8 +7645,8 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Scalex, prefix + "waves23_scalex", T(0.05))); m_Params.push_back(ParamWithName(&m_Scaley, prefix + "waves23_scaley", T(0.05))); - m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves23_freqx", T(7.0))); - m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves23_freqy", T(13.0))); + m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves23_freqx", 7)); + m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves23_freqy", 13)); m_Params.push_back(ParamWithName(true, &m_Freqx12Pi, prefix + "waves23_freqx_12pi"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Freqy12Pi, prefix + "waves23_freqy_12pi")); } @@ -7543,11 +7729,11 @@ protected: m_Params.clear(); m_Params.push_back(ParamWithName(&m_Scalex, prefix + "waves42_scalex", T(0.05))); m_Params.push_back(ParamWithName(&m_Scaley, prefix + "waves42_scaley", T(0.05))); - m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves42_freqx", T(7.0))); - m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves42_freqy", T(13.0))); - m_Params.push_back(ParamWithName(&m_Cont, prefix + "waves42_cont", T(0), eParamType::INTEGER, T(0), T(1))); + m_Params.push_back(ParamWithName(&m_Freqx, prefix + "waves42_freqx", 7)); + m_Params.push_back(ParamWithName(&m_Freqy, prefix + "waves42_freqy", 13)); + m_Params.push_back(ParamWithName(&m_Cont, prefix + "waves42_cont", 0, eParamType::INTEGER, 0, 1)); m_Params.push_back(ParamWithName(&m_Yfact, prefix + "waves42_yfact", T(0.1))); - m_Params.push_back(ParamWithName(&m_Freqx2, prefix + "waves42_freqx2", T(1.0))); + m_Params.push_back(ParamWithName(&m_Freqx2, prefix + "waves42_freqx2", 1)); m_Params.push_back(ParamWithName(true, &m_Yfact001, prefix + "waves42_yfact001"));//Precalc. } @@ -7731,8 +7917,8 @@ protected: m_Params.push_back(ParamWithName(&m_Posy, prefix + "vignette_posy")); m_Params.push_back(ParamWithName(&m_Innerradius, prefix + "vignette_inner_radius", T(0.5))); m_Params.push_back(ParamWithName(&m_Faderadius, prefix + "vignette_fade_radius", T(0.5), eParamType::REAL_NONZERO)); - m_Params.push_back(ParamWithName(&m_Power, prefix + "vignette_power", T(4.0), eParamType::REAL_NONZERO)); - m_Params.push_back(ParamWithName(&m_Blur, prefix + "vignette_blur", T(1.0))); + m_Params.push_back(ParamWithName(&m_Power, prefix + "vignette_power", 4, eParamType::REAL_NONZERO)); + m_Params.push_back(ParamWithName(&m_Blur, prefix + "vignette_blur", 1)); m_Params.push_back(ParamWithName(true, &m_InnerabsPrecalc, prefix + "vignette_inner_abs_precalc"));//Precalc. m_Params.push_back(ParamWithName(true, &m_FadeabsPrecalc, prefix + "vignette_fade_abs_precalc")); m_Params.push_back(ParamWithName(true, &m_PowerhelperPrecalc, prefix + "vignette_power_helper_precalc")); diff --git a/Source/Ember/Variations08.h b/Source/Ember/Variations08.h index 4933f01..e9e0ddf 100644 --- a/Source/Ember/Variations08.h +++ b/Source/Ember/Variations08.h @@ -104,8 +104,8 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_GnarlyCellSize, prefix + "gnarly_cellsize", T(1))); - m_Params.push_back(ParamWithName(&m_GnarlyTwist, prefix + "gnarly_twist", T(1))); + m_Params.push_back(ParamWithName(&m_GnarlyCellSize, prefix + "gnarly_cellsize", 1)); + m_Params.push_back(ParamWithName(&m_GnarlyTwist, prefix + "gnarly_twist", 1)); m_Params.push_back(ParamWithName(true, &m_R2, prefix + "gnarly_r2"));//Precalc. } @@ -300,7 +300,7 @@ protected: { string prefix = Prefix(); m_Params.clear(); - m_Params.push_back(ParamWithName(&m_Size, prefix + "hex_modulus_size", T(1.0))); + m_Params.push_back(ParamWithName(&m_Size, prefix + "hex_modulus_size", 1)); m_Params.push_back(ParamWithName(true, &m_HsizePrecalc, prefix + "hex_modulus_hsize_precalc"));//Precalc. m_Params.push_back(ParamWithName(true, &m_WeightPrecalc, prefix + "hex_modulus_weight_precalc")); } diff --git a/Source/Ember/XmlToEmber.cpp b/Source/Ember/XmlToEmber.cpp index c28bf3b..2a78868 100644 --- a/Source/Ember/XmlToEmber.cpp +++ b/Source/Ember/XmlToEmber.cpp @@ -55,8 +55,8 @@ XmlToEmber::XmlToEmber() { "pow_correctn", "pow_block_correctn" }, { "pow_correctd", "pow_block_correctd" }, { "pow_power", "pow_block_power" }, - { "lt", "linearT_powX" }, //linearT. - { "lt", "linearT_powY" }, + { "lt_powx", "linearT_powX" }, //linearT. + { "lt_powy", "linearT_powY" }, { "re_a", "Mobius_Re_A" }, //Mobius. { "im_a", "Mobius_Im_A" }, { "re_b", "Mobius_Re_B" }, @@ -136,12 +136,12 @@ XmlToEmber::XmlToEmber() { "nb_exactcalc", "nBlur_exactCalc" }, { "nb_highlightedges", "nBlur_highlightEdges" }, { "octapol_r", "octapol_radius" }, //octapol. - { "number_of_stripes", "bubbleT3D_number_of_stripes" }, //bubbleT3D. - { "ratio_of_stripes", "bubbleT3D_ratio_of_stripes" }, - { "angle_of_hole", "bubbleT3D_angle_of_hole" }, - { "exponentZ", "bubbleT3D_exponentZ" }, - { "_symmetryZ", "bubbleT3D_symmetryZ" }, - { "_modusBlur", "bubbleT3D_modusBlur" }, + //{ "number_of_stripes", "bubbleT3D_number_of_stripes" }, //bubbleT3D. + //{ "ratio_of_stripes", "bubbleT3D_ratio_of_stripes" }, + //{ "angle_of_hole", "bubbleT3D_angle_of_hole" }, + //{ "exponentZ", "bubbleT3D_exponentZ" }, + //{ "_symmetryZ", "bubbleT3D_symmetryZ" }, + //{ "_modusBlur", "bubbleT3D_modusBlur" }, { "post_scrop_power", "post_smartcrop_power" }, //post_smartcrop. { "post_scrop_radius", "post_smartcrop_radius" }, { "post_scrop_roundstr", "post_smartcrop_roundstr" }, @@ -164,20 +164,20 @@ XmlToEmber::XmlToEmber() { "tf_exponent", "Truchet_fill_exponent" }, { "tf_arc_width", "Truchet_fill_arc_width" }, { "tf_seed", "Truchet_fill_seed" }, - { "blockSize", "randCubes_blockSize" }, - { "blockHeight", "randCubes_blockHeight" }, - { "spread", "randCubes_spread" }, - { "seed", "randCubes_seed" }, - { "density", "randCubes_density" }, - { "radius", "concentric_radius" }, + //{ "blockSize", "randCubes_blockSize" }, + //{ "blockHeight", "randCubes_blockHeight" }, + //{ "spread", "randCubes_spread" }, + //{ "seed", "randCubes_seed" }, + //{ "density", "randCubes_density" }, + //{ "radius", "concentric_radius" }, //{ "density", "concentric_density" },//Can't have two, which means you can never properly paste from Apophysis with both of these in one xform. - { "r_blur", "concentric_R_blur" }, - { "z_blur", "concentric_Z_blur" }, - { "angle", "pixel_flow_angle" }, - { "len", "pixel_flow_len" }, - { "width", "pixel_flow_width" }, + //{ "r_blur", "concentric_R_blur" }, + //{ "z_blur", "concentric_Z_blur" }, + //{ "angle", "pixel_flow_angle" }, + ///{ "len", "pixel_flow_len" }, + //{ "width", "pixel_flow_width" }, //{ "seed", "pixel_flow_seed" },//randCubes above already uses "seed", but it's just for randomness, so it shouldn't matter. - { "enable_dc", "pixel_flow_enable_dc" }, + //{ "enable_dc", "pixel_flow_enable_dc" }, { "radial_gaussian_angle", "radial_blur_angle" }, { "pr_a", "projective_A" }, { "pr_b", "projective_B" }, @@ -202,7 +202,7 @@ XmlToEmber::XmlToEmber() { "oscope_frequency", "oscilloscope_frequency" }, { "oscope_amplitude", "oscilloscope_amplitude" }, { "oscope_damping", "oscilloscope_damping" }, - { "power", "scry2_power" }, + //{ "power", "scry2_power" }, { "faber_w_angle", "w_angle" }, { "faber_w_hypergon", "w_hypergon" }, { "faber_w_hypergon_n", "w_hypergon_n" }, @@ -240,21 +240,26 @@ XmlToEmber::XmlToEmber() { "post_sshape_roundwidth", "post_smartshape_roundwidth" }, { "post_sshape_distortion", "post_smartshape_distortion" }, { "post_sshape_compensation", "post_smartshape_compensation" }, - { "mult_x", "unicorngaloshen_mult_x" }, - { "mult_y", "unicorngaloshen_mult_y" }, - { "sine", "unicorngaloshen_sine" }, - { "sin_x_amplitude", "unicorngaloshen_sin_x_amplitude" }, - { "sin_x_freq", "unicorngaloshen_sin_x_freq" }, - { "sin_y_amplitude", "unicorngaloshen_sin_y_amplitude" }, - { "sin_y_freq", "unicorngaloshen_sin_y_freq" }, - { "mode", "unicorngaloshen_mode" }, + //{ "mult_x", "unicorngaloshen_mult_x" }, + //{ "mult_y", "unicorngaloshen_mult_y" }, + //{ "sine", "unicorngaloshen_sine" }, + //{ "sin_x_amplitude", "unicorngaloshen_sin_x_amplitude" }, + //{ "sin_x_freq", "unicorngaloshen_sin_x_freq" }, + //{ "sin_y_amplitude", "unicorngaloshen_sin_y_amplitude" }, + //{ "sin_y_freq", "unicorngaloshen_sin_y_freq" }, + //{ "mode", "unicorngaloshen_mode" }, { "d_spher_weight", "d_spherical_weight" }, { "poincare_p", "poincare2_p" }, { "poincare_q", "poincare2_q" }, { "phoenix_power", "phoenix_julia_power"}, { "phoenix_dist", "phoenix_julia_dist" }, - { "x_distort", "phoenix_julia_x_distort"}, - { "y_distort", "phoenix_julia_y_distort" } + //{ "x_distort", "phoenix_julia_x_distort"}, + //{ "y_distort", "phoenix_julia_y_distort" }, + { "phoenixjulia_power", "phoenix_julia_power" }, + { "phoenixjulia_dist", "phoenix_julia_dist" }, + { "phoenixjulia_x_distort", "phoenix_julia_x_distort" }, + { "phoenixjulia_y_distort", "phoenix_julia_y_distort" }, + { "log_", "log" }//Chaotica uses log_ as the weight for log to avoid a name conflict with the function log(). }; m_FlattenNames = { @@ -908,6 +913,8 @@ bool XmlToEmber::ParseEmberElementFromChaos(xmlNode* emberNode, Ember& cur { const auto corrvarname = GetCorrectedVariationName(m_BadVariationNames, varname); const auto corrwprefix = !StartsWith(corrvarname, prefix) ? prefix + corrvarname : corrvarname; + const auto varnamewithunderscore = corrvarname + "_"; + const auto fullprefix = prefix + varnamewithunderscore; if (auto var = m_VariationList->GetVariation(corrwprefix)) { @@ -949,16 +956,28 @@ bool XmlToEmber::ParseEmberElementFromChaos(xmlNode* emberNode, Ember& cur } else if (ParseAndAssignContent(paramsChildNode, "name", paramname, val)) { - auto paramstr = GetCorrectedParamName(m_BadParamNames, ToLower(paramname).c_str()); + auto paramstr = GetCorrectedParamName(m_BadParamNames, paramname); - if (paramname == varname)//Compare non corrected names. + //Compare non corrected or corrected names. + //This is needed for the case of "log_" which gets corrected to "log". + if (paramname == varname || paramstr == varname) { varCopy->m_Weight = val; } else if (parvar) { - if (!StartsWith(paramstr, prefix)) + if (StartsWith(paramstr, fullprefix, true)) + { + //Do nothing. + } + else if (!StartsWith(paramstr, varnamewithunderscore, true) && (prefix.size() == 0 || !StartsWith(paramstr, prefix, true))) + { + paramstr = fullprefix + paramstr; + } + else if (StartsWith(paramstr, varnamewithunderscore, true)) + { paramstr = prefix + paramstr; + } //Need some special corrections here because Chaotica allows values that don't make sense. if (varname == "falloff2") @@ -2412,10 +2431,40 @@ bool XmlToEmber::ParseXform(xmlNode* childNode, Xform& xform, bool motion, { if (const auto parVar = dynamic_cast*>(xform.GetVariation(i))) { + string prefix; + + if (!fromEmber) + { + if (parVar->VarType() == eVariationType::VARTYPE_PRE) + prefix = "pre_"; + else if (parVar->VarType() == eVariationType::VARTYPE_POST) + prefix = "post_"; + } + for (curAtt = attPtr; curAtt; curAtt = curAtt->next) { //Only correct names if it came from an outside source. Names originating from this library are always considered correct. string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedParamName(m_BadParamNames, ToLower(CCX(curAtt->name)).c_str()); + + if (!fromEmber) + { + auto varnamewithunderscore = parVar->m_Name + "_"; + auto fullprefix = prefix + varnamewithunderscore; + + if (StartsWith(s, fullprefix, true)) + { + //Do nothing. + } + else if (!StartsWith(s, varnamewithunderscore, true) && (prefix.size() == 0 || !StartsWith(s, prefix, true))) + { + s = fullprefix + s; + } + else if (StartsWith(s, varnamewithunderscore, true)) + { + s = prefix + s; + } + } + const char* name = s.c_str(); if (parVar->ContainsParam(name)) @@ -2504,8 +2553,12 @@ string XmlToEmber::GetCorrectedVariationName(vector template string XmlToEmber::GetCorrectedVariationName(vector, vector>>& vec, const string& varname) { - if (varname == "poincare")//for Apo flames, poincare must be the same, but chaotica poincare is implemented as poincare2 + if (varname == "poincare")//for Apo flames, poincare must be the same, but Chaotica poincare is implemented as poincare2 return "poincare2"; + else if (varname == "fisheye") + return "eyefish";//Chaotica automatically uses eyefish instead of fisheye. + else if (varname == "phoenixjulia") + return "phoenix_julia"; else if (varname != "mobius")//Chaotica actually gets this right, but Apophysis doesn't. for (auto& v : vec) if (!_stricmp(v.first.first.c_str(), varname.c_str()))//Do case insensitive here. diff --git a/Source/EmberCL/EmberCLStructs.h b/Source/EmberCL/EmberCLStructs.h index af6f71c..b5c1d8d 100644 --- a/Source/EmberCL/EmberCLStructs.h +++ b/Source/EmberCL/EmberCLStructs.h @@ -76,7 +76,9 @@ static string ConstantDefinesString(bool doublePrecision) "#define CUBE(x) ((x) * (x) * (x))\n" "#define MPI ((real_t)M_PI)\n" "#define MPI2 ((real_t)M_PI_2)\n" + "#define MPI3 ((real_t)(1.0471975511965977461542144610932))\n" "#define MPI4 ((real_t)M_PI_4)\n" + "#define MPI6 ((real_t)(0.52359877559829887307710723054658))\n" "#define M1PI ((real_t)M_1_PI)\n" "#define M2PI ((real_t)M_2_PI)\n" "#define M_2PI (MPI * 2)\n" @@ -87,8 +89,6 @@ static string ConstantDefinesString(bool doublePrecision) "#define M_SQRT5 ((real_t)(2.2360679774997896964091736687313))\n" "#define M_PHI ((real_t)(1.61803398874989484820458683436563))\n" "#define M_1_2PI ((real_t)(0.15915494309189533576888376337251))\n" - "#define M_PI3 ((real_t)(1.0471975511965977461542144610932))\n" - "#define M_PI6 ((real_t)(0.52359877559829887307710723054658))\n" "#define DEG_2_RAD (MPI / 180)\n" "#define CURVES_LENGTH_M1 ((real_bucket_t)" << CURVES_LENGTH_M1 << ")\n" << "#define ONE_OVER_CURVES_LENGTH_M1 ((real_bucket_t)" << ONE_OVER_CURVES_LENGTH_M1 << ")\n" << diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 42b98e2..1f58818 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -43,7 +43,7 @@ using namespace Imath; using namespace EmberNs; using namespace EmberCommon; -#define DO_NVIDIA 1 +//#define DO_NVIDIA 1 void writeRgba1(const char filename[], const Rgba* pixels, @@ -2251,15 +2251,53 @@ int _tmain(int argc, _TCHAR* argv[]) size_t times = 1'000'000'001; QTIsaac rand; std::vector vec(16, 0); + double accum = 0; Timing t(4); /* - for (size_t i = 1; i < times; i++) - { - auto res = rand.Rand() % i; - vec[res & 15]++; - } + for (size_t i = 0; i < times; i++) + { + auto res = rand.Frand11(); + auto flr = (double)(Floor(res)); + accum += flr; + } - t.Toc("rand mod"); + t.Toc("Floor"); + cout << accum << endl; + accum = 0; + t.Tic(); + + for (size_t i = 0; i < times; i++) + { + auto res = rand.Frand11(); + auto flr = std::floor(res); + accum += flr; + } + + t.Toc("std::floor"); + cout << accum << endl; + + t.Tic(); + + for (size_t i = 0; i < times; i++) + { + accum += rand.Frand01(); + } + + t.Toc("Frand01"); + cout << accum << endl; + accum = 0; + t.Tic(); + + for (size_t i = 0; i < times; i++) + { + accum += rand.Frand(static_cast(0), static_cast(1)); + } + + t.Toc("Frand(0, 1)"); + cout << accum << endl; + return 1; + */ + /* for (auto& it : vec) { @@ -2443,126 +2481,136 @@ int _tmain(int argc, _TCHAR* argv[]) //TestCross(rand.Frand(-5, 5), rand.Frand(-5, 5), rand.Frand(-5, 5)); //std::complex cd, cd2; //cd2 = sin(cd); - t.Tic(); - TestCasting(); - t.Toc("TestCasting()"); - t.Tic(); - auto vlf(VariationList::Instance()); - t.Toc("Creating VariationList"); - cout << "There are " << vlf->Size() << " variations present." << endl; -#ifdef DO_DOUBLE - t.Tic(); - auto vld(VariationList::Instance()); - t.Toc("Creating VariationList"); -#endif - t.Tic(); - TestVarCounts(); - t.Toc("TestVarCounts()"); - t.Tic(); - TestVarUnique(); - t.Toc("TestVarUnique()"); -#ifdef DO_DOUBLE - t.Tic(); - TestVarUnique(); - t.Toc("TestVarUnique()"); -#endif - t.Tic(); - TestVarCopy(); - t.Toc("TestVarCopy()"); -#ifdef DO_DOUBLE - t.Tic(); - TestVarCopy(); - t.Toc("TestVarCopy()"); - t.Tic(); - TestVarCopy(); - t.Toc("TestVarCopy()"); - t.Tic(); - TestVarCopy(); - t.Toc("TestVarCopy()"); -#endif - t.Tic(); - TestVarRegPrePost(); - t.Toc("TestVarRegPrePost()"); - t.Tic(); - TestParVars(); - t.Toc("TestParVars()"); - t.Tic(); - TestVarPrePostNames(); - t.Toc("TestVarPrePostNames()"); - t.Tic(); - TestVarPrecalcUsedCL(); - t.Toc("TestVarPrecalcUsedCL()"); - t.Tic(); - TestVarAssignTypes(); - t.Toc("TestVarAssignTypes()"); - t.Tic(); - TestVarAssignVals(); - t.Toc("TestVarAssignVals()"); - t.Tic(); - TestZepsFloor(); - t.Toc("TestZepsFloor()"); - t.Tic(); - TestConstants(); - t.Toc("TestConstants()"); - t.Tic(); - TestGlobalFuncs(); - t.Toc("TestGlobalFuncs()"); - /* t.Tic(); - TestXformsInOutPoints(); - t.Toc("TestXformsInOutPoints()"); - - t.Tic(); - TestVarTime(); - t.Toc("TestVarTime()"); - */ - t.Tic(); - TestOperations(); - t.Toc("TestOperations()"); - t.Tic(); - TestArbitrary(); - t.Toc("TestArbitrary()"); - //t.Tic(); - //TestVarsSimilar(); - //t.Toc("TestVarsSimilar()"); -#ifdef TEST_CL - //t.Tic(); - //TestCpuGpuResults(); - //t.Toc("TestCpuGpuResults()"); - //t.Tic(); - //b = TestAllVarsCLBuild(0, 0, true); - //t.Toc("TestAllVarsCLBuild()"); - - if (b) + auto testfunc = [&]() { -#ifdef DO_NVIDIA t.Tic(); - b = TestAllVarsCLBuild(1, 0, true); - t.Toc("TestAllVarsCLBuild()"); -#endif - } - + TestCasting(); + t.Toc("TestCasting()"); + t.Tic(); + auto vlf(VariationList::Instance()); + t.Toc("Creating VariationList"); + cout << "There are " << vlf->Size() << " variations present." << endl; #ifdef DO_DOUBLE + t.Tic(); + auto vld(VariationList::Instance()); + t.Toc("Creating VariationList"); +#endif + t.Tic(); + TestVarCounts(); + t.Toc("TestVarCounts()"); + t.Tic(); + TestVarUnique(); + t.Toc("TestVarUnique()"); +#ifdef DO_DOUBLE + t.Tic(); + TestVarUnique(); + t.Toc("TestVarUnique()"); +#endif + t.Tic(); + TestVarCopy(); + t.Toc("TestVarCopy()"); +#ifdef DO_DOUBLE + t.Tic(); + TestVarCopy(); + t.Toc("TestVarCopy()"); + t.Tic(); + TestVarCopy(); + t.Toc("TestVarCopy()"); + t.Tic(); + TestVarCopy(); + t.Toc("TestVarCopy()"); +#endif + t.Tic(); + TestVarRegPrePost(); + t.Toc("TestVarRegPrePost()"); + t.Tic(); + TestParVars(); + t.Toc("TestParVars()"); + t.Tic(); + TestVarPrePostNames(); + t.Toc("TestVarPrePostNames()"); + t.Tic(); + TestVarPrecalcUsedCL(); + t.Toc("TestVarPrecalcUsedCL()"); + t.Tic(); + TestVarAssignTypes(); + t.Toc("TestVarAssignTypes()"); + t.Tic(); + TestVarAssignVals(); + t.Toc("TestVarAssignVals()"); + t.Tic(); + TestZepsFloor(); + t.Toc("TestZepsFloor()"); + t.Tic(); + TestConstants(); + t.Toc("TestConstants()"); + t.Tic(); + TestGlobalFuncs(); + t.Toc("TestGlobalFuncs()"); + /* t.Tic(); + TestXformsInOutPoints(); + t.Toc("TestXformsInOutPoints()"); - //t.Tic(); - //TestCpuGpuResults(); - //t.Toc("TestCpuGpuResults()"); - if (b) - { + t.Tic(); + TestVarTime(); + t.Toc("TestVarTime()"); + */ + t.Tic(); + TestOperations(); + t.Toc("TestOperations()"); + t.Tic(); + TestArbitrary(); + t.Toc("TestArbitrary()"); //t.Tic(); - //b = TestAllVarsCLBuild(0, 0, true); - //t.Toc("TestAllVarsCLBuild()"); + //TestVarsSimilar(); + //t.Toc("TestVarsSimilar()"); +#ifdef TEST_CL + //t.Tic(); + //TestCpuGpuResults(); + //t.Toc("TestCpuGpuResults()"); + t.Tic(); + b = TestAllVarsCLBuild(0, 0, true); + t.Toc("TestAllVarsCLBuild()"); + if (b) { #ifdef DO_NVIDIA t.Tic(); - TestAllVarsCLBuild(1, 0, true); - t.Toc("TestAllVarsCLBuild()"); + b = TestAllVarsCLBuild(1, 0, true); + t.Toc("TestAllVarsCLBuild()"); #endif } - } + +#ifdef DO_DOUBLE + + //t.Tic(); + //TestCpuGpuResults(); + //t.Toc("TestCpuGpuResults()"); + if (b) + { + t.Tic(); + b = TestAllVarsCLBuild(0, 0, true); + t.Toc("TestAllVarsCLBuild()"); + + if (b) + { +#ifdef DO_NVIDIA + t.Tic(); + TestAllVarsCLBuild(1, 0, true); + t.Toc("TestAllVarsCLBuild()"); +#endif + } + } #endif #endif + }; + cout << "\n\nTesting in compatibility mode:\n\n"; + Compat::m_Compat = true; + testfunc(); + cout << "\n\nTesting in non-compatibility mode:\n\n"; + Compat::m_Compat = false; + testfunc(); //PrintAllVars(); //_CrtDumpMemoryLeaks(); return 0; diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 44462a1..777fb70 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -2409,7 +2409,7 @@ 860 10 295 - 700 + 761 @@ -2461,7 +2461,7 @@ 0 0 307 - 674 + 712 @@ -2954,7 +2954,7 @@ - <html><head/><body><p>Reset all of the curves to their default position. This has the effect of disabling application of the color curves.</p></body></html> + <html><head/><body><p>Reset the currently selected curve to its default position.</p><p>Ctrl + click resets all curves. This has the effect of disabling application of the color curves.</p></body></html> Reset Curves diff --git a/Source/Fractorium/FractoriumXaos.cpp b/Source/Fractorium/FractoriumXaos.cpp index ae4a3de..065304b 100644 --- a/Source/Fractorium/FractoriumXaos.cpp +++ b/Source/Fractorium/FractoriumXaos.cpp @@ -1,7 +1,7 @@ #include "FractoriumPch.h" #include "Fractorium.h" -#define XAOS_PREC 6 +#define XAOS_PREC 8 /// /// Initialize the xforms xaos UI. diff --git a/Source/Fractorium/FractoriumXformsAffine.cpp b/Source/Fractorium/FractoriumXformsAffine.cpp index 162aada..6f2e059 100644 --- a/Source/Fractorium/FractoriumXformsAffine.cpp +++ b/Source/Fractorium/FractoriumXformsAffine.cpp @@ -6,7 +6,7 @@ /// void Fractorium::InitXformsAffineUI() { - const auto affinePrec = 6; + const auto affinePrec = 8; const auto spinHeight = 20; const auto affineStep = 0.01; const auto affineMin = std::numeric_limits::lowest(); diff --git a/Source/Fractorium/Main.cpp b/Source/Fractorium/Main.cpp index 86f9c0e..1b7dbc7 100644 --- a/Source/Fractorium/Main.cpp +++ b/Source/Fractorium/Main.cpp @@ -28,11 +28,11 @@ int main(int argc, char* argv[]) int rv = -1; QApplication a(argc, argv); #ifdef TEST_CL - QMessageBox::critical(QApplication::desktop(), "Error", "Fractorium cannot be run in test mode, undefine TEST_CL first."); + QMessageBox::critical(nullptr, "Error", "Fractorium cannot be run in test mode, undefine TEST_CL first."); return 1; #endif #ifdef ISAAC_FLAM3_DEBUG - QMessageBox::critical(QApplication::desktop(), "Error", "Fractorium cannot be run in test mode, undefine ISAAC_FLAM3_DEBUG first."); + QMessageBox::critical(nullptr, "Error", "Fractorium cannot be run in test mode, undefine ISAAC_FLAM3_DEBUG first."); return 1; #endif _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); diff --git a/Source/Fractorium/OptionsDialog.ui b/Source/Fractorium/OptionsDialog.ui index cdb3af4..90772fb 100644 --- a/Source/Fractorium/OptionsDialog.ui +++ b/Source/Fractorium/OptionsDialog.ui @@ -246,7 +246,7 @@ - <html><head/><body><p>The behavior of the cos, cosh, cot, coth, csc, csch, sec, sech, sin, sinh, tan and tanh variations are different in flam3/Apophysis versus Chaotica.</p><p>Checked: use the Apophysis behavior.</p><p>Unchecked: use the Chaotica behavior.</p></body></html> + <html><head/><body><p>The behavior of the asteria, bipolar, circlecrop, cos, cosh, cot, coth, cropn, cross, csc, csch, depth_ngon2, depth_sine2, edisc, escher, fan2, glynnia, hypershift, hypershift2, hypertile1, julia, julian, juliascope, loonie2, npolar, phoenix_julia, sec, sech, sin, sinh, sphericaln, tan, tanh, and truchet variations are different in flam3/Apophysis versus Chaotica.</p><p>Checked: use the Apophysis behavior.</p><p>Unchecked: use the Chaotica behavior.</p></body></html> Flam3 Compatibility