#pragma once
#include "Variation.h"
namespace EmberNs
{
///
/// eSwirl.
///
template
class ESwirlVariation : public ParametricVariation
{
public:
ESwirlVariation(T weight = 1.0) : ParametricVariation("eSwirl", eVariationId::VAR_ESWIRL, weight, true)
{
Init();
}
PARVARCOPY(ESwirlVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T tmp = helper.m_PrecalcSumSquares + 1;
T tmp2 = 2 * helper.In.x;
T xmax = (VarFuncs::SafeSqrt(tmp + tmp2) + VarFuncs::SafeSqrt(tmp - tmp2)) * T(0.5);
ClampGteRef(xmax, -1);
T mu = std::acosh(xmax);
T nu = std::acos(Clamp(helper.In.x / xmax, -1, 1));//-Pi < nu < Pi.
if (helper.In.y < 0)
nu *= -1;
nu = nu + mu * m_Out + m_In / mu;
helper.Out.x = m_Weight * std::cosh(mu) * std::cos(nu);
helper.Out.y = m_Weight * std::sinh(mu) * std::sin(nu);
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string in = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string out = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t 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"
<< "\n"
<< "\t\tif (xmax < 1)\n"
<< "\t\t xmax = 1;\n"
<< "\n"
<< "\t\treal_t mu = acosh(xmax);\n"
<< "\t\treal_t nu = acos(clamp(vIn.x / xmax, -(real_t)(1.0), (real_t)(1.0)));\n"
<< "\n"
<< "\t\tif (vIn.y < 0)\n"
<< "\t\t nu *= -1;\n"
<< "\n"
<< "\t\tnu = nu + mu * " << out << " + " << in << " / mu;\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * cosh(mu) * cos(nu);\n"
<< "\t\tvOut.y = " << weight << " * sinh(mu) * sin(nu);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "SafeSqrt" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_In, prefix + "eSwirl_in"));
m_Params.push_back(ParamWithName(&m_Out, prefix + "eSwirl_out"));
}
private:
T m_In;
T m_Out;
};
///
/// lazyTravis.
///
template
class LazyTravisVariation : public ParametricVariation
{
public:
LazyTravisVariation(T weight = 1.0) : ParametricVariation("lazyTravis", eVariationId::VAR_LAZY_TRAVIS, weight)
{
Init();
}
PARVARCOPY(LazyTravisVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = std::abs(helper.In.x);
T y = std::abs(helper.In.y);
T s;
T p;
T x2, y2;
if (x > m_Weight || y > m_Weight)
{
if (x > y)
{
s = x;
if (helper.In.x > 0)
p = s + helper.In.y + s * m_Out4;
else
p = 5 * s - helper.In.y + s * m_Out4;
}
else
{
s = y;
if (helper.In.y > 0)
p = 3 * s - helper.In.x + s * m_Out4;
else
p = 7 * s + helper.In.x + s * m_Out4;
}
p = fmod(p, s * 8);
if (p <= 2 * s)
{
x2 = s + m_Space;
y2 = -(1 * s - p);
y2 = y2 + y2 / s * m_Space;
}
else if (p <= 4 * s)
{
y2 = s + m_Space;
x2 = (3 * s - p);
x2 = x2 + x2 / s * m_Space;
}
else if (p <= 6 * s)
{
x2 = -(s + m_Space);
y2 = (5 * s - p);
y2 = y2 + y2 / s * m_Space;
}
else
{
y2 = -(s + m_Space);
x2 = -(7 * s - p);
x2 = x2 + x2 / s * m_Space;
}
helper.Out.x = m_Weight * x2;
helper.Out.y = m_Weight * y2;
}
else
{
if (x > y)
{
s = x;
if (helper.In.x > 0)
p = s + helper.In.y + s * m_In4;
else
p = 5 * s - helper.In.y + s * m_In4;
}
else
{
s = y;
if (helper.In.y > 0)
p = 3 * s - helper.In.x + s * m_In4;
else
p = 7 * s + helper.In.x + s * m_In4;
}
p = fmod(p, s * 8);
if (p <= 2 * s)
{
helper.Out.x = m_Weight * s;
helper.Out.y = -(m_Weight * (s - p));
}
else if (p <= 4 * s)
{
helper.Out.x = m_Weight * (3 * s - p);
helper.Out.y = m_Weight * s;
}
else if (p <= 6 * s)
{
helper.Out.x = -(m_Weight * s);
helper.Out.y = m_Weight * (5 * s - p);
}
else
{
helper.Out.x = -(m_Weight * (7 * s - p));
helper.Out.y = -(m_Weight * s);
}
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string spinIn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string spinOut = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string space = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string in4 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string out4 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = fabs(vIn.x);\n"
<< "\t\treal_t y = fabs(vIn.y);\n"
<< "\t\treal_t s;\n"
<< "\t\treal_t p;\n"
<< "\t\treal_t x2, y2;\n"
<< "\n"
<< "\t\tif (x > " << weight << " || y > " << weight << ")\n"
<< "\t\t{\n"
<< "\t\t if (x > y)\n"
<< "\t\t {\n"
<< "\t\t s = x;\n"
<< "\n"
<< "\t\t if (vIn.x > 0)\n"
<< "\t\t p = s + vIn.y + s * " << out4 << ";\n"
<< "\t\t else\n"
<< "\t\t p = 5 * s - vIn.y + s * " << out4 << ";\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t s = y;\n"
<< "\n"
<< "\t\t if (vIn.y > 0)\n"
<< "\t\t p = 3 * s - vIn.x + s * " << out4 << ";\n"
<< "\t\t else\n"
<< "\t\t p = 7 * s + vIn.x + s * " << out4 << ";\n"
<< "\t\t }\n"
<< "\n"
<< "\t\t p = fmod(p, s * 8);\n"
<< "\n"
<< "\t\t if (p <= 2 * s)\n"
<< "\t\t {\n"
<< "\t\t x2 = s + " << space << ";\n"
<< "\t\t y2 = -(1 * s - p);\n"
<< "\t\t y2 = y2 + y2 / s * " << space << ";\n"
<< "\t\t }\n"
<< "\t\t else if (p <= 4 * s)\n"
<< "\t\t {\n"
<< "\t\t y2 = s + " << space << ";\n"
<< "\t\t x2 = (3 * s - p);\n"
<< "\t\t x2 = x2 + x2 / s * " << space << ";\n"
<< "\t\t }\n"
<< "\t\t else if (p <= 6 * s)\n"
<< "\t\t {\n"
<< "\t\t x2 = -(s + " << space << ");\n"
<< "\t\t y2 = (5 * s - p);\n"
<< "\t\t y2 = y2 + y2 / s * " << space << ";\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t y2 = -(s + " << space << ");\n"
<< "\t\t x2 = -(7 * s - p);\n"
<< "\t\t x2 = x2 + x2 / s * " << space << ";\n"
<< "\t\t }\n"
<< "\n"
<< "\t\t vOut.x = " << weight << " * x2;\n"
<< "\t\t vOut.y = " << weight << " * y2;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (x > y)\n"
<< "\t\t {\n"
<< "\t\t s = x;\n"
<< "\n"
<< "\t\t if (vIn.x > 0)\n"
<< "\t\t p = s + vIn.y + s * " << in4 << ";\n"
<< "\t\t else\n"
<< "\t\t p = 5 * s - vIn.y + s * " << in4 << ";\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t s = y;\n"
<< "\n"
<< "\t\t if (vIn.y > 0)\n"
<< "\t\t p = 3 * s - vIn.x + s * " << in4 << ";\n"
<< "\t\t else\n"
<< "\t\t p = 7 * s + vIn.x + s * " << in4 << ";\n"
<< "\t\t }\n"
<< "\n"
<< "\t\t p = fmod(p, s * 8);\n"
<< "\n"
<< "\t\t if (p <= 2 * s)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = " << weight << " * s;\n"
<< "\t\t vOut.y = -(" << weight << " * (s - p));\n"
<< "\t\t }\n"
<< "\t\t else if (p <= 4 * s)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = " << weight << " * (3 * s - p);\n"
<< "\t\t vOut.y = " << weight << " * s;\n"
<< "\t\t }\n"
<< "\t\t else if (p <= 6 * s)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = -(" << weight << " * s);\n"
<< "\t\t vOut.y = " << weight << " * (5 * s - p);\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = -(" << weight << " * (7 * s - p));\n"
<< "\t\t vOut.y = -(" << weight << " * s);\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_In4 = 4 * m_SpinIn;
m_Out4 = 4 * m_SpinOut;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_SpinIn, prefix + "lazyTravis_spin_in", 1, eParamType::REAL_CYCLIC, 0, 2));
m_Params.push_back(ParamWithName(&m_SpinOut, prefix + "lazyTravis_spin_out", 0, eParamType::REAL_CYCLIC, 0, 2));
m_Params.push_back(ParamWithName(&m_Space, prefix + "lazyTravis_space"));
m_Params.push_back(ParamWithName(true, &m_In4, prefix + "lazyTravis_in4"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Out4, prefix + "lazyTravis_out4"));
}
private:
T m_SpinIn;
T m_SpinOut;
T m_Space;
T m_In4;//Precalc.
T m_Out4;
};
///
/// squish.
///
template
class SquishVariation : public ParametricVariation
{
public:
SquishVariation(T weight = 1.0) : ParametricVariation("squish", eVariationId::VAR_SQUISH, weight)
{
Init();
}
PARVARCOPY(SquishVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = std::abs(helper.In.x);
T y = std::abs(helper.In.y);
T s;
T p;
if (x > y)
{
s = x;
if (helper.In.x > 0)
p = helper.In.y;
else
p = 4 * s - helper.In.y;
}
else
{
s = y;
if (helper.In.y > 0)
p = 2 * s - helper.In.x;
else
p = 6 * s + helper.In.x;
}
p = m_InvPower * (p + 8 * s * Floor(m_Power * rand.Frand01()));
if (p <= s)
{
helper.Out.x = m_Weight * s;
helper.Out.y = m_Weight * p;
}
else if (p <= 3 * s)
{
helper.Out.x = m_Weight * (2 * s - p);
helper.Out.y = m_Weight * s;
}
else if (p <= 5 * s)
{
helper.Out.x = -(m_Weight * s);
helper.Out.y = m_Weight * (4 * s - p);
}
else if (p <= 7 * s)
{
helper.Out.x = -(m_Weight * (6 * s - p));
helper.Out.y = -(m_Weight * s);
}
else
{
helper.Out.x = m_Weight * s;
helper.Out.y = (m_Weight * (8 * s - p));
}
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string invPower = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = fabs(vIn.x);\n"
<< "\t\treal_t y = fabs(vIn.y);\n"
<< "\t\treal_t s;\n"
<< "\t\treal_t p;\n"
<< "\n"
<< "\t\tif (x > y)\n"
<< "\t\t{\n"
<< "\t\t s = x;\n"
<< "\n"
<< "\t\t if (vIn.x > 0)\n"
<< "\t\t p = vIn.y;\n"
<< "\t\t else\n"
<< "\t\t p = 4 * s - vIn.y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t s = y;\n"
<< "\n"
<< "\t\t if (vIn.y > 0)\n"
<< "\t\t p = 2 * s - vIn.x;\n"
<< "\t\t else\n"
<< "\t\t p = 6 * s + vIn.x;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tp = " << invPower << " * (p + 8 * s * floor(" << power << " * MwcNext01(mwc)));\n"
<< "\n"
<< "\t\tif (p <= s)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * s;\n"
<< "\t\t vOut.y = " << weight << " * p;\n"
<< "\t\t}\n"
<< "\t\telse if (p <= 3 * s)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * (2 * s - p);\n"
<< "\t\t vOut.y = " << weight << " * s;\n"
<< "\t\t}\n"
<< "\t\telse if (p <= 5 * s)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = -(" << weight << " * s);\n"
<< "\t\t vOut.y = " << weight << " * (4 * s - p);\n"
<< "\t\t}\n"
<< "\t\telse if (p <= 7 * s)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = -(" << weight << " * (6 * s - p));\n"
<< "\t\t vOut.y = -(" << weight << " * s);\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * s;\n"
<< "\t\t vOut.y = -(" << weight << " * (8 * s - p));\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_InvPower = 1 / m_Power;
}
protected:
void Init()
{
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(true, &m_InvPower, prefix + "squish_inv_power"));//Precalc.
}
private:
T m_Power;
T m_InvPower;//Precalc.
};
///
/// circus.
///
template
class CircusVariation : public ParametricVariation
{
public:
CircusVariation(T weight = 1.0) : ParametricVariation("circus", eVariationId::VAR_CIRCUS, weight, true, true, true)
{
Init();
}
PARVARCOPY(CircusVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = helper.m_PrecalcSqrtSumSquares;
if (r <= 1)
r *= m_Scale;
else
r *= m_InvScale;
helper.Out.x = m_Weight * r * helper.m_PrecalcCosa;
helper.Out.y = m_Weight * r * helper.m_PrecalcSina;
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string invScale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = precalcSqrtSumSquares;\n"
<< "\n"
<< "\t\tif (r <= 1)\n"
<< "\t\t r *= " << scale << ";\n"
<< "\t\telse\n"
<< "\t\t r *= " << invScale << ";\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * r * precalcCosa;\n"
<< "\t\tvOut.y = " << weight << " * r * precalcSina;\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_InvScale = 1 / m_Scale;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Scale, prefix + "circus_scale", 1));
m_Params.push_back(ParamWithName(true, &m_InvScale, prefix + "circus_inv_power"));//Precalc.
}
private:
T m_Scale;
T m_InvScale;//Precalc.
};
///
/// tancos.
///
template
class TancosVariation : public Variation
{
public:
TancosVariation(T weight = 1.0) : Variation("tancos", eVariationId::VAR_TANCOS, weight, true) { }
VARCOPY(TancosVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T d = Zeps(helper.m_PrecalcSumSquares);
helper.Out.x = (m_Weight / d) * (std::tanh(d) * (2 * helper.In.x));
helper.Out.y = (m_Weight / d) * (std::cos(d) * (2 * helper.In.y));
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\treal_t d = Zeps(precalcSumSquares);\n"
<< "\n"
<< "\t\tvOut.x = (" << weight << " / d) * (tanh(d) * ((real_t)(2.0) * vIn.x));\n"
<< "\t\tvOut.y = (" << weight << " / d) * (cos(d) * ((real_t)(2.0) * vIn.y));\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
};
///
/// rippled.
///
template
class RippledVariation : public Variation
{
public:
RippledVariation(T weight = 1.0) : Variation("rippled", eVariationId::VAR_RIPPLED, weight, true) { }
VARCOPY(RippledVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T d = Zeps(helper.m_PrecalcSumSquares);
helper.Out.x = (m_Weight / 2) * (std::tanh(d) * (2 * helper.In.x));
helper.Out.y = (m_Weight / 2) * (std::cos(d) * (2 * helper.In.y));
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\treal_t d = Zeps(precalcSumSquares);\n"
<< "\n"
<< "\t\tvOut.x = (" << weight << " / (real_t)(2.0)) * (tanh(d) * ((real_t)(2.0) * vIn.x));\n"
<< "\t\tvOut.y = (" << weight << " / (real_t)(2.0)) * (cos(d) * ((real_t)(2.0) * vIn.y));\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
};
///
/// RotateX.
/// This uses in/out in a rare and different way.
///
template
class RotateXVariation : public ParametricVariation
{
public:
RotateXVariation(T weight = 1.0) : ParametricVariation("rotate_x", eVariationId::VAR_ROTATE_X, weight)
{
Init();
}
PARVARCOPY(RotateXVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T z = m_RxCos * helper.In.z - m_RxSin * helper.In.y;
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.x = helper.In.x;
outPoint.m_X = 0;
}
else
{
helper.Out.x = helper.In.x;
}
helper.Out.y = m_RxSin * helper.In.z + m_RxCos * helper.In.y;
helper.Out.z = z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
int i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string rxSin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params.
string rxCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t z = " << rxCos << " * vIn.z - " << rxSin << " * vIn.y;\n"
<< "\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.x = 0;\n"
"\t\toutPoint->m_X = vIn.x;\n";
}
else
{
ss <<
"\t\tvOut.x = vIn.x;\n";
}
ss << "\t\tvOut.y = " << rxSin << " * vIn.z + " << rxCos << " * vIn.y;\n"
<< "\t\tvOut.z = z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_RxSin = std::sin(m_Weight * T(M_PI_2));
m_RxCos = std::cos(m_Weight * T(M_PI_2));
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(true, &m_RxSin, prefix + "rotate_x_sin"));//Precalcs only, no params.
m_Params.push_back(ParamWithName(true, &m_RxCos, prefix + "rotate_x_cos"));//Original used a prefix of rx_, which is incompatible with Ember's design.
}
private:
T m_RxSin;
T m_RxCos;
};
///
/// RotateY.
/// This uses in/out in a rare and different way.
///
template
class RotateYVariation : public ParametricVariation
{
public:
RotateYVariation(T weight = 1.0) : ParametricVariation("rotate_y", eVariationId::VAR_ROTATE_Y, weight)
{
Init();
}
PARVARCOPY(RotateYVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_RyCos * helper.In.x - m_RySin * helper.In.z;
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.y = 0;
outPoint.m_Y = helper.In.y;
}
else
{
helper.Out.y = helper.In.y;
}
helper.Out.z = m_RySin * helper.In.x + m_RyCos * helper.In.z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
int i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string rySin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params.
string ryCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tvOut.x = " << ryCos << " * vIn.x - " << rySin << " * vIn.z;\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.y = 0;\n"
"\t\toutPoint->m_Y = vIn.y;\n";
}
else
{
ss <<
"\t\tvOut.y = vIn.y;\n";
}
ss << "\t\tvOut.z = " << rySin << " * vIn.x + " << ryCos << " * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_RySin = std::sin(m_Weight * T(M_PI_2));
m_RyCos = std::cos(m_Weight * T(M_PI_2));
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(true, &m_RySin, prefix + "rotate_y_sin"));//Precalcs only, no params.
m_Params.push_back(ParamWithName(true, &m_RyCos, prefix + "rotate_y_cos"));//Original used a prefix of ry_, which is incompatible with Ember's design.
}
private:
T m_RySin;
T m_RyCos;
};
///
/// RotateZ.
/// This was originally pre and post spin_z, consolidated here to be consistent with the other rotate variations.
///
template
class RotateZVariation : public ParametricVariation
{
public:
RotateZVariation(T weight = 1.0) : ParametricVariation("rotate_z", eVariationId::VAR_ROTATE_Z, weight)
{
Init();
}
PARVARCOPY(RotateZVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_RzSin * helper.In.y + m_RzCos * helper.In.x;
helper.Out.y = m_RzCos * helper.In.y - m_RzSin * helper.In.x;
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.z = helper.In.z;
outPoint.m_Z = 0;
}
else
{
helper.Out.z = helper.In.z;
}
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
int i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string rzSin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params.
string rzCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tvOut.x = " << rzSin << " * vIn.y + " << rzCos << " * vIn.x;\n"
<< "\t\tvOut.y = " << rzCos << " * vIn.y - " << rzSin << " * vIn.x;\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.z = 0;\n"
"\t\toutPoint->m_Z = vIn.z;\n";
}
else
{
ss <<
"\t\tvOut.z = vIn.z;\n";
}
ss << "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_RzSin = std::sin(m_Weight * T(M_PI_2));
m_RzCos = std::cos(m_Weight * T(M_PI_2));
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(true, &m_RzSin, prefix + "rotate_z_sin"));//Precalcs only, no params.
m_Params.push_back(ParamWithName(true, &m_RzCos, prefix + "rotate_z_cos"));
}
private:
T m_RzSin;
T m_RzCos;
};
///
/// MirrorX.
/// This uses in/out in a rare and different way.
///
template
class MirrorXVariation : public Variation
{
public:
MirrorXVariation(T weight = 1.0) : Variation("mirror_x", eVariationId::VAR_MIRROR_X, weight) { }
VARCOPY(MirrorXVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.x = std::abs(outPoint.m_X);
if (rand.RandBit())
helper.Out.x = -helper.Out.x;
helper.Out.y = 0;
helper.Out.z = 0;
outPoint.m_X = 0;//Flipped x will be added.
}
else
{
helper.Out.x = std::abs(helper.In.x);
if (rand.RandBit())
helper.Out.x = -helper.Out.x;
helper.Out.y = helper.In.y;
helper.Out.z = helper.In.z;
}
}
virtual string OpenCLString() const override
{
ostringstream ss;
ss << "\t{\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.x = fabs(outPoint->m_X);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.x = -vOut.x;\n"
"\n"
"\t\tvOut.y = 0;\n"
"\t\tvOut.z = 0;\n"
"\t\toutPoint->m_X = 0;\n";
}
else
{
ss <<
"\t\tvOut.x = fabs(vIn.x);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.x = -vOut.x;\n"
"\n"
"\t\tvOut.y = vIn.y;\n"
"\t\tvOut.z = vIn.z;\n";
}
ss << "\t}\n";
return ss.str();
}
};
///
/// MirrorY.
/// This uses in/out in a rare and different way.
///
template
class MirrorYVariation : public Variation
{
public:
MirrorYVariation(T weight = 1.0) : Variation("mirror_y", eVariationId::VAR_MIRROR_Y, weight) { }
VARCOPY(MirrorYVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.y = std::abs(outPoint.m_Y);
if (rand.RandBit())
helper.Out.y = -helper.Out.y;
helper.Out.x = 0;
helper.Out.z = 0;
outPoint.m_Y = 0;//Flipped y will be added.
}
else
{
helper.Out.y = std::abs(helper.In.y);
if (rand.RandBit())
helper.Out.y = -helper.Out.y;
helper.Out.x = helper.In.x;
helper.Out.z = helper.In.z;
}
}
virtual string OpenCLString() const override
{
ostringstream ss;
ss << "\t{\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.y = fabs(outPoint->m_Y);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.y = -vOut.y;\n"
"\n"
"\t\tvOut.x = 0;\n"
"\t\tvOut.z = 0;\n"
"\t\toutPoint->m_Y = 0;\n";
}
else
{
ss <<
"\t\tvOut.y = fabs(vIn.y);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.y = -vOut.y;\n"
"\n"
"\t\tvOut.x = vIn.x;\n"
"\t\tvOut.z = vIn.z;\n";
}
ss << "\t}\n";
return ss.str();
}
};
///
/// MirrorZ.
/// This uses in/out in a rare and different way.
///
template
class MirrorZVariation : public Variation
{
public:
MirrorZVariation(T weight = 1.0) : Variation("mirror_z", eVariationId::VAR_MIRROR_Z, weight) { }
VARCOPY(MirrorZVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == eVariationType::VARTYPE_REG)
{
helper.Out.z = std::abs(outPoint.m_Z);
if (rand.RandBit())
helper.Out.z = -helper.Out.z;
helper.Out.x = 0;
helper.Out.y = 0;
outPoint.m_Z = 0;//Flipped z will be added.
}
else
{
helper.Out.z = std::abs(helper.In.z);
if (rand.RandBit())
helper.Out.z = -helper.Out.z;
helper.Out.x = helper.In.x;
helper.Out.y = helper.In.y;
}
}
virtual string OpenCLString() const override
{
ostringstream ss;
ss << "\t{\n";
if (m_VarType == eVariationType::VARTYPE_REG)
{
ss <<
"\t\tvOut.z = fabs(outPoint->m_Z);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.z = -vOut.z;\n"
"\n"
"\t\tvOut.x = 0;\n"
"\t\tvOut.y = 0;\n"
"\t\toutPoint->m_Z = 0;\n";
}
else
{
ss <<
"\t\tvOut.z = fabs(vIn.z);\n"
"\n"
"\t\tif (MwcNext(mwc) & 1)\n"
"\t\t vOut.z = -vOut.z;\n"
"\n"
"\t\tvOut.x = vIn.x;\n"
"\t\tvOut.y = vIn.y;\n";
}
ss << "\t}\n";
return ss.str();
}
};
///
/// RBlur.
///
template
class RBlurVariation : public ParametricVariation
{
public:
RBlurVariation(T weight = 1.0) : ParametricVariation("rblur", eVariationId::VAR_RBLUR, weight)
{
Init();
}
PARVARCOPY(RBlurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T sx = helper.In.x - m_CenterX;
T sy = helper.In.y - m_CenterY;
T r = std::sqrt(SQR(sx) + SQR(sy)) - m_Offset;
r = r < 0 ? 0 : r;
r *= m_S2;
helper.Out.x = m_Weight * (helper.In.x + (rand.Frand01() - T(0.5)) * r);
helper.Out.y = m_Weight * (helper.In.y + (rand.Frand01() - T(0.5)) * r);
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string strength = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string centerX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string centerY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string s2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t sx = vIn.x - " << centerX << ";\n"
<< "\t\treal_t sy = vIn.y - " << centerY << ";\n"
<< "\t\treal_t r = sqrt(SQR(sx) + SQR(sy)) - " << offset << ";\n"
<< "\n"
<< "\t\tr = r < 0 ? 0 : r;\n"
<< "\t\tr *= " << s2 << ";\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * (vIn.x + (MwcNext01(mwc) - (real_t)(0.5)) * r);\n"
<< "\t\tvOut.y = " << weight << " * (vIn.y + (MwcNext01(mwc) - (real_t)(0.5)) * r);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_S2 = 2 * m_Strength;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Strength, prefix + "rblur_strength", 1));
m_Params.push_back(ParamWithName(&m_Offset, prefix + "rblur_offset", 1));
m_Params.push_back(ParamWithName(&m_CenterX, prefix + "rblur_center_x"));
m_Params.push_back(ParamWithName(&m_CenterY, prefix + "rblur_center_y"));
m_Params.push_back(ParamWithName(true, &m_S2, prefix + "rblur_s2"));//Precalc.
}
private:
T m_Strength;
T m_Offset;
T m_CenterX;
T m_CenterY;
T m_S2;//Precalc.
};
///
/// JuliaNab.
///
template
class JuliaNabVariation : public ParametricVariation
{
public:
JuliaNabVariation(T weight = 1.0) : ParametricVariation("juliaNab", eVariationId::VAR_JULIANAB, weight, true)
{
Init();
}
PARVARCOPY(JuliaNabVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T jun = Zeps(std::abs(m_N));
T a = (std::atan2(helper.In.y, std::pow(std::abs(helper.In.x), m_Sep)) + M_2PI * Floor(rand.Frand01() * m_AbsN)) / jun;
T r = m_Weight * std::pow(helper.m_PrecalcSumSquares, m_Cn * m_A);
helper.Out.x = r * std::cos(a) + m_B;
helper.Out.y = r * std::sin(a) + m_B;
helper.Out.z = helper.In.z;
if (m_VarType == eVariationType::VARTYPE_REG)
outPoint.m_Z = 0;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string b = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string sep = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string absN = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t jun = Zeps(fabs(" << n << "));\n"
<< "\n"
<< "\t\treal_t a = (atan2(vIn.y, pow(fabs(vIn.x), " << sep << ")) + M_2PI * floor(MwcNext01(mwc) * " << absN << ")) / jun;\n"
<< "\t\treal_t r = " << weight << " * pow(precalcSumSquares, " << cn << " * " << a << ");\n"
<< "\n"
<< "\t\tvOut.x = r * cos(a) + " << b << ";\n"
<< "\t\tvOut.y = r * sin(a) + " << b << ";\n"
<< "\t\tvOut.z = vIn.z;\n";
if (m_VarType == eVariationType::VARTYPE_REG)
ss << "\t\toutPoint->m_Z = 0;\n";
ss
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
virtual void Precalc() override
{
T jun = Zeps(std::abs(m_N));
m_AbsN = abs(m_N);
m_Cn = 1 / jun / 2;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "juliaNab_n", 1));
m_Params.push_back(ParamWithName(&m_A, prefix + "juliaNab_a", 1));
m_Params.push_back(ParamWithName(&m_B, prefix + "juliaNab_b", 1));
m_Params.push_back(ParamWithName(&m_Sep, prefix + "juliaNab_separ", 1));
m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "juliaNab_absn"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "juliaNab_cn"));
}
private:
T m_N;
T m_A;
T m_B;
T m_Sep;
T m_AbsN;//Precalc.
T m_Cn;
};
///
/// Sintrange.
///
template
class SintrangeVariation : public ParametricVariation
{
public:
SintrangeVariation(T weight = 1.0) : ParametricVariation("sintrange", eVariationId::VAR_SINTRANGE, weight)
{
Init();
}
PARVARCOPY(SintrangeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T sqX = SQR(helper.In.x);
T sqY = SQR(helper.In.y);
T v = (sqX + sqY) * m_W;//Do not use precalcSumSquares here because its components are needed below.
helper.Out.x = m_Weight * std::sin(helper.In.x) * (sqX + m_W - v);
helper.Out.y = m_Weight * std::sin(helper.In.y) * (sqY + m_W - v);
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string w = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t sqX = SQR(vIn.x);\n"
<< "\t\treal_t sqY = SQR(vIn.y);\n"
<< "\t\treal_t v = (sqX + sqY) * " << w << ";\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * sin(vIn.x) * (sqX + " << w << " - v);\n"
<< "\t\tvOut.y = " << weight << " * sin(vIn.y) * (sqY + " << w << " - v);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_W, prefix + "sintrange_w", 1));
}
private:
T m_W;
};
///
/// Voron.
///
template
class VoronVariation : public ParametricVariation
{
public:
VoronVariation(T weight = 1.0) : ParametricVariation("Voron", eVariationId::VAR_VORON, weight)
{
Init();
}
PARVARCOPY(VoronVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
intmax_t l, k;
int i, j, m, m1, n, n1;
T r, rMin, offsetX, offsetY, x0 = 0, y0 = 0, x, y;
rMin = 20;
m = int(Floor(helper.In.x / m_Step));
n = int(Floor(helper.In.y / m_Step));
for (i = -1; i < 2; i++)
{
m1 = m + i;
for (j = -1; j < 2; j++)
{
n1 = n + j;
k = 1 + Floor(m_Num * DiscreteNoise(int(19 * m1 + 257 * n1 + m_XSeed)));
for (l = 0; l < k; l++)
{
x = T(DiscreteNoise(int(l + 64 * m1 + 15 * n1 + m_XSeed)) + m1) * m_Step;
y = T(DiscreteNoise(int(l + 21 * m1 + 33 * n1 + m_YSeed)) + n1) * m_Step;
offsetX = helper.In.x - x;
offsetY = helper.In.y - y;
r = std::sqrt(SQR(offsetX) + SQR(offsetY));
if (r < rMin)
{
rMin = r;
x0 = x;
y0 = y;
}
}
}
}
helper.Out.x = m_Weight * (m_K * (helper.In.x - x0) + x0);
helper.Out.y = m_Weight * (m_K * (helper.In.y - y0) + y0);
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string m_k = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string step = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string num = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string xSeed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ySeed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tint i, j, l, k, m, m1, n, n1;\n"
<< "\t\treal_t r, rMin, offsetX, offsetY, x0 = (real_t)(0.0), y0 = (real_t)(0.0), x, y;\n"
<< "\n"
<< "\t\trMin = 20;\n"
<< "\t\tm = (int)floor(vIn.x / " << step << ");\n"
<< "\t\tn = (int)floor(vIn.y / " << step << ");\n"
<< "\n"
<< "\t\tfor (i = -1; i < 2; i++)\n"
<< "\t\t{\n"
<< "\t\t m1 = m + i;\n"
<< "\n"
<< "\t\t for (j = -1; j < 2; j++)\n"
<< "\t\t {\n"
<< "\t\t n1 = n + j;\n"
<< "\t\t k = 1 + (int)floor(" << num << " * VoronDiscreteNoise((int)(19 * m1 + 257 * n1 + " << xSeed << ")));\n"
<< "\n"
<< "\t\t for (l = 0; l < k; l++)\n"
<< "\t\t {\n"
<< "\t\t x = (real_t)(VoronDiscreteNoise((int)(l + 64 * m1 + 15 * n1 + " << xSeed << ")) + m1) * " << step << ";\n"
<< "\t\t y = (real_t)(VoronDiscreteNoise((int)(l + 21 * m1 + 33 * n1 + " << ySeed << ")) + n1) * " << step << ";\n"
<< "\t\t offsetX = vIn.x - x;\n"
<< "\t\t offsetY = vIn.y - y;\n"
<< "\t\t r = sqrt(SQR(offsetX) + SQR(offsetY));\n"
<< "\n"
<< "\t\t if (r < rMin)\n"
<< "\t\t {\n"
<< "\t\t rMin = r;\n"
<< "\t\t x0 = x;\n"
<< "\t\t y0 = y;\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = " << weight << " * (" << m_k << " * (vIn.x - x0) + x0);\n"
<< "\t\tvOut.y = " << weight << " * (" << m_k << " * (vIn.y - y0) + y0);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual string OpenCLFuncsString() const override
{
return
"real_t VoronDiscreteNoise(int x)\n"
"{\n"
" const real_t im = 2147483647;\n"
" const real_t am = (1 / im);\n"
"\n"
" int n = x;\n"
" n = (n << 13) ^ n;\n"
" return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am;\n"
"}\n"
"\n";
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_K, prefix + "Voron_K", T(0.99)));
m_Params.push_back(ParamWithName(&m_Step, prefix + "Voron_Step", T(0.25), eParamType::REAL_NONZERO));
m_Params.push_back(ParamWithName(&m_Num, prefix + "Voron_Num", 1, eParamType::INTEGER, 1, 25));
m_Params.push_back(ParamWithName(&m_XSeed, prefix + "Voron_XSeed", 3, eParamType::INTEGER));
m_Params.push_back(ParamWithName(&m_YSeed, prefix + "Voron_YSeed", 7, eParamType::INTEGER));
}
private:
T DiscreteNoise(int x)
{
const T im = T(2147483647);
const T am = (1 / im);
int n = x;
n = (n << 13) ^ n;
return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am;
}
T m_K;//Params.
T m_Step;
T m_Num;
T m_XSeed;
T m_YSeed;
};
///
/// Waffle.
///
template
class WaffleVariation : public ParametricVariation
{
public:
WaffleVariation(T weight = 1.0) : ParametricVariation("waffle", eVariationId::VAR_WAFFLE, weight)
{
Init();
}
PARVARCOPY(WaffleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T a = 0, r = 0;
switch (rand.Rand(5))
{
case 0:
a = (rand.Rand(ISAAC_INT(m_Slices)) + rand.Frand01() * m_XThickness) / m_Slices;
r = (rand.Rand(ISAAC_INT(m_Slices)) + rand.Frand01() * m_YThickness) / m_Slices;
break;
case 1:
a = (rand.Rand(ISAAC_INT(m_Slices)) + rand.Frand01()) / m_Slices;
r = (rand.Rand(ISAAC_INT(m_Slices)) + m_YThickness) / m_Slices;
break;
case 2:
a = (rand.Rand(ISAAC_INT(m_Slices)) + m_XThickness) / m_Slices;
r = (rand.Rand(ISAAC_INT(m_Slices)) + rand.Frand01()) / m_Slices;
break;
case 3:
a = rand.Frand01();
r = (rand.Rand(ISAAC_INT(m_Slices)) + m_YThickness + rand.Frand01() * (1 - m_YThickness)) / m_Slices;
break;
case 4:
default:
a = (rand.Rand(ISAAC_INT(m_Slices)) + m_XThickness + rand.Frand01() * (1 - m_XThickness)) / m_Slices;
r = rand.Frand01();
break;
}
helper.Out.x = m_CosR * a + m_SinR * r;
helper.Out.y = -m_SinR * a + m_CosR * r;
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
int i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string xThickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string yThickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rotation = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string sinr = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cosr = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t a = 0, r = 0;\n"
<< "\n"
<< "\t\tswitch (MwcNextRange(mwc, 5))\n"
<< "\t\t{\n"
<< "\t\t case 0:\n"
<< "\t\t a = (MwcNextRange(mwc, (int)" << slices << ") + MwcNext01(mwc) * " << xThickness << ") / " << slices << ";\n"
<< "\t\t r = (MwcNextRange(mwc, (int)" << slices << ") + MwcNext01(mwc) * " << yThickness << ") / " << slices << ";\n"
<< "\t\t break;\n"
<< "\t\t case 1:\n"
<< "\t\t a = (MwcNextRange(mwc, (int)" << slices << ") + MwcNext01(mwc)) / " << slices << ";\n"
<< "\t\t r = (MwcNextRange(mwc, (int)" << slices << ") + " << yThickness << ") / " << slices << ";\n"
<< "\t\t break;\n"
<< "\t\t case 2:\n"
<< "\t\t a = (MwcNextRange(mwc, (int)" << slices << ") + " << xThickness << ") / " << slices << ";\n"
<< "\t\t r = (MwcNextRange(mwc, (int)" << slices << ") + MwcNext01(mwc)) / " << slices << ";\n"
<< "\t\t break;\n"
<< "\t\t case 3:\n"
<< "\t\t a = MwcNext01(mwc);\n"
<< "\t\t r = (MwcNextRange(mwc, (int)" << slices << ") + " << yThickness << " + MwcNext01(mwc) * (1 - " << yThickness << ")) / " << slices << ";\n"
<< "\t\t break;\n"
<< "\t\t case 4:\n"
<< "\t\t a = (MwcNextRange(mwc, (int)" << slices << ") + " << xThickness << " + MwcNext01(mwc) * (1 - " << xThickness << ")) / " << slices << ";\n"
<< "\t\t r = MwcNext01(mwc);\n"
<< "\t\t break;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = " << cosr << " * a + " << sinr << " * r;\n"
<< "\t\tvOut.y = -" << sinr << " * a + " << cosr << " * r;\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_SinR = std::sin(m_Rotation);
m_CosR = std::cos(m_Rotation);
}
protected:
void Init()
{
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_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"));
m_Params.push_back(ParamWithName(true, &m_SinR, prefix + "waffle_sinr"));
m_Params.push_back(ParamWithName(true, &m_CosR, prefix + "waffle_cosr"));
}
private:
T m_Slices;
T m_XThickness;
T m_YThickness;
T m_Rotation;
T m_SinR;//Precalc.
T m_CosR;
};
///
/// Square3D.
///
template
class Square3DVariation : public Variation
{
public:
Square3DVariation(T weight = 1.0) : Variation("square3D", eVariationId::VAR_SQUARE3D, weight) { }
VARCOPY(Square3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_Weight * (rand.Frand01() - T(0.5));
helper.Out.y = m_Weight * (rand.Frand01() - T(0.5));
helper.Out.z = m_Weight * (rand.Frand01() - T(0.5));
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
string weight = WeightDefineString();
ss << "\t{\n"
<< "\t\tvOut.x = " << weight << " * (MwcNext01(mwc) - (real_t)(0.5));\n"
<< "\t\tvOut.y = " << weight << " * (MwcNext01(mwc) - (real_t)(0.5));\n"
<< "\t\tvOut.z = " << weight << " * (MwcNext01(mwc) - (real_t)(0.5));\n"
<< "\t}\n";
return ss.str();
}
};
///
/// SuperShape3D.
///
template
class SuperShape3DVariation : public ParametricVariation
{
public:
SuperShape3DVariation(T weight = 1.0) : ParametricVariation("SuperShape3D", eVariationId::VAR_SUPER_SHAPE3D, weight)
{
Init();
}
PARVARCOPY(SuperShape3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T pr1, r1, pr2, r2, rho1, phi1, sinr, sinp, cosr, cosp, msinr, msinp, mcosr, mcosp, temp;
rho1 = rand.Frand01() * m_Rho2Pi;
phi1 = rand.Frand01() * m_Phi2Pi;
if (rand.RandBit())
phi1 = -phi1;
sinr = std::sin(rho1);
cosr = std::cos(rho1);
sinp = std::sin(phi1);
cosp = std::cos(phi1);
temp = m_M4_1 * rho1;
msinr = std::sin(temp);
mcosr = std::cos(temp);
temp = m_M4_2 * phi1;
msinp = std::sin(temp);
mcosp = std::cos(temp);
pr1 = m_An2_1 * std::pow(std::abs(mcosr), m_N2_1) + m_Bn3_1 * std::pow(std::abs(msinr), m_N3_1);
pr2 = m_An2_2 * std::pow(std::abs(mcosp), m_N2_2) + m_Bn3_2 * std::pow(std::abs(msinp), m_N3_2);
r1 = std::pow(std::abs(pr1), m_N1_1) + m_Spiral * rho1;
r2 = std::pow(std::abs(pr2), m_N1_2);
if (int(m_Toroidmap) == 1)
{
helper.Out.x = m_Weight * cosr * (r1 + r2 * cosp);
helper.Out.y = m_Weight * sinr * (r1 + r2 * cosp);
helper.Out.z = m_Weight * r2 * sinp;
}
else
{
helper.Out.x = m_Weight * r1 * cosr * r2 * cosp;
helper.Out.y = m_Weight * r1 * sinr * r2 * cosp;
helper.Out.z = m_Weight * r2 * sinp;
}
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string rho = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string m1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string m2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string a1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string a2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string b1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string b2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n1_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n1_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n2_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n2_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n3_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n3_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string spiral = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string toroid = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n1n_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n1n_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string an2_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string an2_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bn3_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bn3_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string m4_1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string m4_2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rho2pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi2pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t pr1, r1, pr2, r2, rho1, phi1, sinr, sinp, cosr, cosp, msinr, msinp, mcosr, mcosp, temp;\n"
<< "\n"
<< "\t\trho1 = MwcNext01(mwc) * " << rho2pi << ";\n"
<< "\t\tphi1 = MwcNext01(mwc) * " << phi2pi << ";\n"
<< "\n"
<< "\t\tif (MwcNext(mwc) & 1)\n"
<< "\t\t phi1 = -phi1;\n"
<< "\n"
<< "\t\tsinr = sin(rho1);\n"
<< "\t\tcosr = cos(rho1);\n"
<< "\n"
<< "\t\tsinp = sin(phi1);\n"
<< "\t\tcosp = cos(phi1);\n"
<< "\n"
<< "\t\ttemp = " << m4_1 << " * rho1;\n"
<< "\t\tmsinr = sin(temp);\n"
<< "\t\tmcosr = cos(temp);\n"
<< "\n"
<< "\t\ttemp = " << m4_2 << " * phi1;\n"
<< "\t\tmsinp = sin(temp);\n"
<< "\t\tmcosp = cos(temp);\n"
<< "\n"
<< "\t\tpr1 = " << an2_1 << " * pow(fabs(mcosr), " << n2_1 << ") + " << bn3_1 << " * pow(fabs(msinr), " << n3_1 << ");\n"
<< "\t\tpr2 = " << an2_2 << " * pow(fabs(mcosp), " << n2_2 << ") + " << bn3_2 << " * pow(fabs(msinp), " << n3_2 << ");\n"
<< "\t\tr1 = pow(fabs(pr1), " << n1_1 << ") + " << spiral << " * rho1;\n"
<< "\t\tr2 = pow(fabs(pr2), " << n1_2 << ");\n"
<< "\n"
<< "\t\tif ((int)" << toroid << " == 1)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * cosr * (r1 + r2 * cosp);\n"
<< "\t\t vOut.y = " << weight << " * sinr * (r1 + r2 * cosp);\n"
<< "\t\t vOut.z = " << weight << " * r2 * sinp;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * r1 * cosr * r2 * cosp;\n"
<< "\t\t vOut.y = " << weight << " * r1 * sinr * r2 * cosp;\n"
<< "\t\t vOut.z = " << weight << " * r2 * sinp;\n"
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_N1n_1 = (-1 / m_N1_1);
m_N1n_2 = (-1 / m_N1_2);
m_An2_1 = std::pow(std::abs(1 / m_A1), m_N2_1);
m_An2_2 = std::pow(std::abs(1 / m_A2), m_N2_2);
m_Bn3_1 = std::pow(std::abs(1 / m_B1), m_N3_1);
m_Bn3_2 = std::pow(std::abs(1 / m_B2), m_N3_2);
m_M4_1 = m_M1 / 4;
m_M4_2 = m_M2 / 4;
m_Rho2Pi = m_Rho * T(M_2_PI);
m_Phi2Pi = m_Phi * T(M_2_PI);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Rho, prefix + "SuperShape3D_rho", T(9.9)));
m_Params.push_back(ParamWithName(&m_Phi, prefix + "SuperShape3D_phi", T(2.5)));
m_Params.push_back(ParamWithName(&m_M1, prefix + "SuperShape3D_m1", 6));
m_Params.push_back(ParamWithName(&m_M2, prefix + "SuperShape3D_m2", 3));
m_Params.push_back(ParamWithName(&m_A1, prefix + "SuperShape3D_a1", 1));
m_Params.push_back(ParamWithName(&m_A2, prefix + "SuperShape3D_a2", 1));
m_Params.push_back(ParamWithName(&m_B1, prefix + "SuperShape3D_b1", 1));
m_Params.push_back(ParamWithName(&m_B2, prefix + "SuperShape3D_b2", 1));
m_Params.push_back(ParamWithName(&m_N1_1, prefix + "SuperShape3D_n1_1", 1));
m_Params.push_back(ParamWithName(&m_N1_2, prefix + "SuperShape3D_n1_2", 1));
m_Params.push_back(ParamWithName(&m_N2_1, prefix + "SuperShape3D_n2_1", 1));
m_Params.push_back(ParamWithName(&m_N2_2, prefix + "SuperShape3D_n2_2", 1));
m_Params.push_back(ParamWithName(&m_N3_1, prefix + "SuperShape3D_n3_1", 1));
m_Params.push_back(ParamWithName(&m_N3_2, prefix + "SuperShape3D_n3_2", 1));
m_Params.push_back(ParamWithName(&m_Spiral, prefix + "SuperShape3D_spiral"));
m_Params.push_back(ParamWithName(&m_Toroidmap, prefix + "SuperShape3D_toroidmap", 0, eParamType::INTEGER, 0, 1));
m_Params.push_back(ParamWithName(true, &m_N1n_1, prefix + "SuperShape3D_n1n1"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_N1n_2, prefix + "SuperShape3D_n1n2"));
m_Params.push_back(ParamWithName(true, &m_An2_1, prefix + "SuperShape3D_an21"));
m_Params.push_back(ParamWithName(true, &m_An2_2, prefix + "SuperShape3D_an22"));
m_Params.push_back(ParamWithName(true, &m_Bn3_1, prefix + "SuperShape3D_bn31"));
m_Params.push_back(ParamWithName(true, &m_Bn3_2, prefix + "SuperShape3D_bn32"));
m_Params.push_back(ParamWithName(true, &m_M4_1, prefix + "SuperShape3D_m41"));
m_Params.push_back(ParamWithName(true, &m_M4_2, prefix + "SuperShape3D_m42"));
m_Params.push_back(ParamWithName(true, &m_Rho2Pi, prefix + "SuperShape3D_rho2pi"));
m_Params.push_back(ParamWithName(true, &m_Phi2Pi, prefix + "SuperShape3D_phi2pi"));
}
private:
T m_Rho;
T m_Phi;
T m_M1;
T m_M2;
T m_A1;
T m_A2;
T m_B1;
T m_B2;
T m_N1_1;
T m_N1_2;
T m_N2_1;
T m_N2_2;
T m_N3_1;
T m_N3_2;
T m_Spiral;
T m_Toroidmap;
T m_N1n_1;//Precalc.
T m_N1n_2;
T m_An2_1;
T m_An2_2;
T m_Bn3_1;
T m_Bn3_2;
T m_M4_1;
T m_M4_2;
T m_Rho2Pi;
T m_Phi2Pi;
};
///
/// sphyp3D.
///
template
class Sphyp3DVariation : public ParametricVariation
{
public:
Sphyp3DVariation(T weight = 1.0) : ParametricVariation("sphyp3D", eVariationId::VAR_SPHYP3D, weight, true)
{
Init();
}
PARVARCOPY(Sphyp3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T t, rX, rY, rZ;
t = Zeps(helper.m_PrecalcSumSquares + SQR(helper.In.z));
rX = m_Weight / std::pow(t, m_StretchX);
rY = m_Weight / std::pow(t, m_StretchY);
helper.Out.x = helper.In.x * rX;
helper.Out.y = helper.In.y * rY;
//Optional 3D calculation.
if (int(m_ZOn) == 1)
{
rZ = m_Weight / std::pow(t, m_StretchZ);
helper.Out.z = helper.In.z * rZ;
}
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string stretchX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string stretchY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string stretchZ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string zOn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t t, rX, rY, rZ;\n"
<< "\n"
<< "\t\tt = Zeps(precalcSumSquares + SQR(vIn.z));\n"
<< "\t\trX = " << weight << " / pow(t, " << stretchX << ");\n"
<< "\t\trY = " << weight << " / pow(t, " << stretchY << ");\n"
<< "\n"
<< "\t\tvOut.x = vIn.x * rX;\n"
<< "\t\tvOut.y = vIn.y * rY;\n"
<< "\n"
<< "\t\tif ((int)" << zOn << " == 1)\n"
<< "\t\t{\n"
<< "\t\trZ = " << weight << " / pow(t, " << stretchZ << ");\n"
<< "\n"
<< "\t\tvOut.z = vIn.z * rZ;\n"
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
virtual vector OpenCLGlobalFuncNames() const override
{
return vector { "Zeps" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_StretchX, prefix + "sphyp3D_stretchX", 1));
m_Params.push_back(ParamWithName(&m_StretchY, prefix + "sphyp3D_stretchY", 1));
m_Params.push_back(ParamWithName(&m_StretchZ, prefix + "sphyp3D_stretchZ", 1));
m_Params.push_back(ParamWithName(&m_ZOn, prefix + "sphyp3D_zOn", 1, eParamType::INTEGER, 0, 1));
}
private:
T m_StretchX;
T m_StretchY;
T m_StretchZ;
T m_ZOn;
};
///
/// circlecrop.
///
template
class CirclecropVariation : public ParametricVariation
{
public:
CirclecropVariation(T weight = 1.0) : ParametricVariation("circlecrop", eVariationId::VAR_CIRCLECROP, weight)
{
Init();
}
PARVARCOPY(CirclecropVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T xi = helper.In.x - m_X;
T yi = helper.In.y - m_Y;
if (m_VarType == eVariationType::VARTYPE_REG)//Original altered the input pointed to for reg.
{
helper.m_TransX -= m_X;
helper.m_TransY -= m_Y;
helper.Out.z = m_Weight * helper.In.z;//Original only assigned z for reg. Will be summed.
}
else
{
helper.Out.z = helper.In.z;//Original did nothing with z for pre/post, so passthrough direct assign.
}
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)
{
helper.Out.x = helper.Out.y = 0;
if (m_VarType == eVariationType::VARTYPE_REG)
outPoint.m_X = outPoint.m_Y = 0;
}
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)
{
helper.Out.x = m_Weight * xi + m_X;
helper.Out.y = m_Weight * yi + m_Y;
}
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
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;
ss << "\t{\n"
<< "\t\treal_t xi = vIn.x - " << x << ";\n"
<< "\t\treal_t yi = vIn.y - " << y << ";\n"
<< "\n";
if (m_VarType == eVariationType::VARTYPE_REG)//Original altered the input pointed to for reg.
{
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\tconst real_t rad = sqrt(SQR(xi) + SQR(yi));\n"
<< "\t\tconst real_t ang = atan2(yi, xi);\n"
<< "\t\tconst real_t rdc = " << radius << " + (MwcNext01(mwc) * (real_t)(0.5) * " << ca << "); \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";
if (m_VarType == eVariationType::VARTYPE_REG)
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 = " << weight << " * xi + " << x << ";\n"
<< "\t\t vOut.y = " << weight << " * yi + " << y << ";\n"
<< "\t\t}\n"
<< "\t\telse if (!cr0 && esc)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * rdc * c + " << x << ";\n"
<< "\t\t vOut.y = " << weight << " * rdc * s + " << y << ";\n"
<< "\t\t}\n"
<< "\t\telse if (!cr0 && !esc)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = " << weight << " * xi + " << x << ";\n"
<< "\t\t vOut.y = " << weight << " * yi + " << y << ";\n"
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Ca = Clamp(m_ScatterArea, -1, 1);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Radius, prefix + "circlecrop_radius", 1));
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(true, &m_Ca, prefix + "circlecrop_ca"));
}
private:
T m_Radius;
T m_X;
T m_Y;
T m_ScatterArea;
T m_Zero;
T m_Ca;//Precalc.
};
///
/// julian3Dx.
///
template
class Julian3DxVariation : public ParametricVariation
{
public:
Julian3DxVariation(T weight = 1.0) : ParametricVariation("julian3Dx", eVariationId::VAR_JULIAN3DX, weight, true, true)
{
Init();
}
PARVARCOPY(Julian3DxVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
const T z = helper.In.z / m_AbsN;
const T radiusOut = m_Weight * std::pow(helper.m_PrecalcSumSquares + z * z, m_Cn);
const T x = m_A * helper.In.x + m_B * helper.In.y + m_E;
const T y = m_C * helper.In.x + m_D * helper.In.y + m_F;
const T tempRand = T(int(rand.Frand01() * m_AbsN));
const T alpha = (std::atan2(y, x) + M_2PI * tempRand) / m_Power;
const T gamma = radiusOut * helper.m_PrecalcSqrtSumSquares;
helper.Out.x = gamma * std::cos(alpha);
helper.Out.y = gamma * std::sin(alpha);
helper.Out.z = radiusOut * z;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string b = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string e = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string f = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string absn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tconst real_t z = vIn.z / " << absn << ";\n"
<< "\t\tconst real_t radiusOut = " << weight << " * pow(precalcSumSquares + z * z, " << cn << ");\n"
<< "\t\tconst real_t x = " << a << " * vIn.x + " << b << " * vIn.y + " << e << ";\n"
<< "\t\tconst real_t y = " << c << " * vIn.x + " << d << " * vIn.y + " << f << ";\n"
<< "\t\tconst real_t rand = (int)(MwcNext01(mwc) * " << absn << ");\n"
<< "\t\tconst real_t alpha = (atan2(y, x) + M_2PI * rand) / " << power << ";\n"
<< "\t\tconst real_t gamma = radiusOut * precalcSqrtSumSquares;\n"
<< "\n"
<< "\t\tvOut.x = gamma * cos(alpha);\n"
<< "\t\tvOut.y = gamma * sin(alpha);\n"
<< "\t\tvOut.z = radiusOut * z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_AbsN = std::abs(m_Power);
m_Cn = (m_Dist / m_Power - 1) / 2;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Dist, prefix + "julian3Dx_dist", 1));
m_Params.push_back(ParamWithName(&m_Power, prefix + "julian3Dx_power", 2, eParamType::INTEGER_NONZERO));
m_Params.push_back(ParamWithName(&m_A, prefix + "julian3Dx_a", 1));
m_Params.push_back(ParamWithName(&m_B, prefix + "julian3Dx_b"));
m_Params.push_back(ParamWithName(&m_C, prefix + "julian3Dx_c"));
m_Params.push_back(ParamWithName(&m_D, prefix + "julian3Dx_d", 1));
m_Params.push_back(ParamWithName(&m_E, prefix + "julian3Dx_e"));
m_Params.push_back(ParamWithName