#pragma once
#include "Variation.h"
namespace EmberNs
{
///
/// Funnel.
///
template
class EMBER_API FunnelVariation : public ParametricVariation
{
public:
FunnelVariation(T weight = 1.0) : ParametricVariation("funnel", VAR_FUNNEL, weight)
{
Init();
}
PARVARCOPY(FunnelVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T temp = 1 / Zeps(cos(helper.In.y)) + m_Effect * T(M_PI);
helper.Out.x = m_Weight * (tanh(helper.In.x) * temp);
helper.Out.y = m_Weight * (tanh(helper.In.y) * temp);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string effect = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t temp = 1 / Zeps(cos(vIn.y)) + " << effect << " * M_PI;\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.x) * temp);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.y) * temp);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Effect, prefix + "funnel_effect", 8, INTEGER));
}
private:
T m_Effect;
};
///
/// Linear3D.
///
template
class EMBER_API Linear3DVariation : public Variation
{
public:
Linear3DVariation(T weight = 1.0) : Variation("linear3D", VAR_LINEAR3D, weight) { }
VARCOPY(Linear3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// PowBlock.
///
template
class EMBER_API PowBlockVariation : public ParametricVariation
{
public:
PowBlockVariation(T weight = 1.0) : ParametricVariation("pow_block", VAR_POW_BLOCK, weight, true, false, false, false, true)
{
Init();
}
PARVARCOPY(PowBlockVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r2 = pow(helper.m_PrecalcSumSquares, m_Power * T(0.5)) * m_Weight;
T ran = (helper.m_PrecalcAtanyx / Zeps(m_Denominator) + (m_Root * M_2PI * Floor(rand.Frand01() * m_Denominator) / Zeps(m_Denominator))) * m_Numerator;
helper.Out.x = r2 * cos(ran);
helper.Out.y = r2 * sin(ran);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string numerator = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string denominator = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string root = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string correctN = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string correctD = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r2 = pow(precalcSumSquares, " << power << " * (real_t)(0.5)) * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\treal_t ran = (precalcAtanyx / Zeps(" << denominator << ") + (" << root << " * M_2PI * floor(MwcNext01(mwc) * " << denominator << ") / Zeps(" << denominator << "))) * " << numerator << ";\n"
<< "\n"
<< "\t\tvOut.x = r2 * cos(ran);\n"
<< "\t\tvOut.y = r2 * sin(ran);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Power = m_Numerator / Zeps(m_Denominator * m_Correctn * (1 / m_Correctd));
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Numerator, prefix + "pow_block_numerator", 3));//Original used a prefix of pow_, which is incompatible with Ember's design.
m_Params.push_back(ParamWithName(&m_Denominator, prefix + "pow_block_denominator", 2));
m_Params.push_back(ParamWithName(&m_Root, prefix + "pow_block_root", 1));
m_Params.push_back(ParamWithName(&m_Correctn, prefix + "pow_block_correctn", 1));
m_Params.push_back(ParamWithName(&m_Correctd, prefix + "pow_block_correctd", 1));
m_Params.push_back(ParamWithName(true, &m_Power, prefix + "pow_block_power"));//Precalc.
}
private:
T m_Numerator;
T m_Denominator;
T m_Root;
T m_Correctn;
T m_Correctd;
T m_Power;//Precalc.
};
///
/// Squirrel.
///
template
class EMBER_API SquirrelVariation : public ParametricVariation
{
public:
SquirrelVariation(T weight = 1.0) : ParametricVariation("squirrel", VAR_SQUIRREL, weight)
{
Init();
}
PARVARCOPY(SquirrelVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T u = sqrt(ClampGte0(Zeps(m_A) * SQR(helper.In.x) + Zeps(m_B) * SQR(helper.In.y)));//Original did not clamp.
helper.Out.x = cos(u) * SafeTan(helper.In.x) * m_Weight;
helper.Out.y = sin(u) * SafeTan(helper.In.y) * m_Weight;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string b = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t u = sqrt(ClampGte(Zeps(" << a << ") * SQR(vIn.x) + Zeps(" << b << ") * SQR(vIn.y), (real_t)(0.0)));\n"
<< "\n"
<< "\t\tvOut.x = cos(u) * tan(vIn.x) * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.y = sin(u) * tan(vIn.y) * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_A, prefix + "squirrel_a", 1));
m_Params.push_back(ParamWithName(&m_B, prefix + "squirrel_b", 1));
}
private:
T m_A;
T m_B;
};
///
/// Ennepers.
///
template
class EMBER_API EnnepersVariation : public Variation
{
public:
EnnepersVariation(T weight = 1.0) : Variation("ennepers", VAR_ENNEPERS, weight) { }
VARCOPY(EnnepersVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_Weight * (helper.In.x - ((SQR(helper.In.x) * helper.In.x) / 3)) + helper.In.x * SQR(helper.In.y);
helper.Out.y = m_Weight * (helper.In.y - ((SQR(helper.In.y) * helper.In.y) / 3)) + helper.In.y * SQR(helper.In.x);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x - ((SQR(vIn.x) * vIn.x) / 3)) + vIn.x * SQR(vIn.y);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y - ((SQR(vIn.y) * vIn.y) / 3)) + vIn.y * SQR(vIn.x);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// SphericalN.
///
template
class EMBER_API SphericalNVariation : public ParametricVariation
{
public:
SphericalNVariation(T weight = 1.0) : ParametricVariation("SphericalN", VAR_SPHERICALN, weight, true, true, false, false, true)
{
Init();
}
PARVARCOPY(SphericalNVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = Zeps(pow(helper.m_PrecalcSqrtSumSquares, m_Dist));
int n = Floor(m_Power * rand.Frand01());
T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Zeps(T(Floor(m_Power)));
T sina = sin(alpha);
T cosa = cos(alpha);
helper.Out.x = m_Weight * cosa / r;
helper.Out.y = m_Weight * sina / r;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = Zeps(pow(precalcSqrtSumSquares, " << dist << "));\n"
<< "\t\tint n = floor(" << power << " * MwcNext01(mwc));\n"
<< "\t\treal_t alpha = precalcAtanyx + n * M_2PI / Zeps(floor(" << power << "));\n"
<< "\t\treal_t sina = sin(alpha);\n"
<< "\t\treal_t cosa = cos(alpha);\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cosa / r;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * sina / r;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Power, prefix + "SphericalN_Power", 1));
m_Params.push_back(ParamWithName(&m_Dist, prefix + "SphericalN_Dist", 1));
}
private:
T m_Power;
T m_Dist;
};
///
/// Kaleidoscope.
///
template
class EMBER_API KaleidoscopeVariation : public ParametricVariation
{
public:
KaleidoscopeVariation(T weight = 1.0) : ParametricVariation("Kaleidoscope", VAR_KALEIDOSCOPE, weight)
{
Init();
}
PARVARCOPY(KaleidoscopeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T sin45 = sin(45 * DEG_2_RAD_T);//Was 45 radians? They probably meant to convert this from degrees.
T cos45 = cos(45 * DEG_2_RAD_T);
helper.Out.x = ((m_Rotate * helper.In.x) * cos45 - helper.In.y * sin45 + m_LineUp) + m_X;
//The if function splits the plugin in two.
if (helper.In.y > 0)
helper.Out.y = ((m_Rotate * helper.In.y) * cos45 + helper.In.x * sin45 + m_Pull + m_LineUp) + m_Y;
else
helper.Out.y = (m_Rotate * helper.In.y) * cos45 + helper.In.x * sin45 - m_Pull - m_LineUp;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string pull = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rotate = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string lineUp = "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;
ss << "\t{\n"
<< "\t\treal_t sin45 = sin(45 * DEG_2_RAD);\n"
<< "\t\treal_t cos45 = cos(45 * DEG_2_RAD);\n"
<< "\n"
<< "\t\tvOut.x = ((" << rotate << " * vIn.x) * cos45 - vIn.y * sin45 + " << lineUp << ") + " << x << ";\n"
<< "\n"
<< "\t\tif (vIn.y > 0)\n"
<< "\t\t vOut.y = ((" << rotate << " * vIn.y) * cos45 + vIn.x * sin45 + " << pull << " + " << lineUp << ") + " << y << ";\n"
<< "\t\telse\n"
<< "\t\t vOut.y = (" << rotate << " * vIn.y) * cos45 + vIn.x * sin45 - " << pull << " - " << lineUp << ";\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Pull, prefix + "Kaleidoscope_pull"));
m_Params.push_back(ParamWithName(&m_Rotate, prefix + "Kaleidoscope_rotate", 1));
m_Params.push_back(ParamWithName(&m_LineUp, prefix + "Kaleidoscope_line_up", 1));
m_Params.push_back(ParamWithName(&m_X, prefix + "Kaleidoscope_x"));
m_Params.push_back(ParamWithName(&m_Y, prefix + "Kaleidoscope_y"));
}
private:
T m_Pull;//Pulls apart the 2 sections of the plugin.
T m_Rotate;//Rotates both halves of the plugin.
T m_LineUp;
T m_X;//Changes x co-ordinates.
T m_Y;//Changes y co-ordinates for 1 part of the plugin.
};
///
/// GlynnSim1.
///
template
class EMBER_API GlynnSim1Variation : public ParametricVariation
{
public:
GlynnSim1Variation(T weight = 1.0) : ParametricVariation("GlynnSim1", VAR_GLYNNSIM1, weight, true, true)
{
Init();
}
PARVARCOPY(GlynnSim1Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x, y, z;
if (helper.m_PrecalcSqrtSumSquares < m_Radius)//Object generation.
{
Circle(rand, &x, &y);
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01() > m_Contrast * pow(alpha, m_Pow))
{
x = helper.In.x;
y = helper.In.y;
}
else
{
x = SQR(alpha) * helper.In.x;
y = SQR(alpha) * helper.In.y;
}
z = Sqr(x - m_X1) + Sqr(y - m_Y1);
if (z < SQR(m_Radius1))//Object generation.
{
Circle(rand, &x, &y);
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string radius1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string contrast = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string pow = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x, y, z;\n"
<< "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius << ")\n"
<< "\t\t{\n"
<< "\t\t GlynnSim1Circle(&" << radius1 << ", &" << thickness << ", &" << x1 << ", &" << y1 << ", mwc, &x, &y);\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n"
<< "\t\t x = vIn.x;\n"
<< "\t\t y = vIn.y;\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t x = SQR(alpha) * vIn.x;\n"
<< "\t\t y = SQR(alpha) * vIn.y;\n"
<< "\t\t }\n"
<< "\n"
<< "\t\t z = Sqr(x - " << x1 << ") + Sqr(y - " << y1 << ");\n"
<< "\n"
<< "\t\t if (z < SQR(" << radius1 << "))\n"
<< "\t\t {\n"
<< "\t\t GlynnSim1Circle(&" << radius1 << ", &" << thickness << ", &" << x1 << ", &" << y1 << ", mwc, &x, &y);\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual string OpenCLFuncsString()
{
return
"void GlynnSim1Circle(__constant real_t* radius1, __constant real_t* thickness, __constant real_t* x1, __constant real_t* y1, uint2* mwc, real_t* x, real_t* y)\n"
"{\n"
" real_t r = *radius1 * (*thickness + ((real_t)(1.0) - *thickness) * MwcNext01(mwc));\n"
" real_t phi = M_2PI * MwcNext01(mwc);\n"
" real_t sinPhi = sin(phi);\n"
" real_t cosPhi = cos(phi);\n"
"\n"
" *x = r * cosPhi + *x1;\n"
" *y = r * sinPhi + *y1;\n"
"}\n"
"\n";
}
virtual void Precalc() override
{
T val = DEG_2_RAD_T * m_Phi1;
T sinPhi1 = sin(val);
T cosPhi1 = cos(val);
m_Pow = fabs(m_Pow);
m_X1 = m_Radius * cosPhi1;
m_Y1 = m_Radius * sinPhi1;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Radius, prefix + "GlynnSim1_radius", 1));
m_Params.push_back(ParamWithName(&m_Radius1, prefix + "GlynnSim1_radius1", T(0.1)));
m_Params.push_back(ParamWithName(&m_Phi1, prefix + "GlynnSim1_phi1"));
m_Params.push_back(ParamWithName(&m_Thickness, prefix + "GlynnSim1_thickness", T(0.1), REAL, 0, 1));
m_Params.push_back(ParamWithName(&m_Contrast, prefix + "GlynnSim1_contrast", T(1.5)));
m_Params.push_back(ParamWithName(&m_Pow, prefix + "GlynnSim1_pow", T(0.5), REAL, 0, 1));
m_Params.push_back(ParamWithName(true, &m_X1, prefix + "GlynnSim1_x1"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Y1, prefix + "GlynnSim1_y1"));
}
private:
void Circle(QTIsaac& rand, T* x, T* y)
{
T r = m_Radius1 * (m_Thickness + (1 - m_Thickness) * rand.Frand01());
T phi = M_2PI * rand.Frand01();
T sinPhi = sin(phi);
T cosPhi = cos(phi);
*x = r * cosPhi + m_X1;
*y = r * sinPhi + m_Y1;
}
T m_Radius;//Params.
T m_Radius1;
T m_Phi1;
T m_Thickness;
T m_Contrast;
T m_Pow;
T m_X1;//Precalc.
T m_Y1;
};
///
/// GlynnSim2.
///
template
class EMBER_API GlynnSim2Variation : public ParametricVariation
{
public:
GlynnSim2Variation(T weight = 1.0) : ParametricVariation("GlynnSim2", VAR_GLYNNSIM2, weight, true, true)
{
Init();
}
PARVARCOPY(GlynnSim2Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x, y;
if (helper.m_PrecalcSqrtSumSquares < m_Radius)
{
Circle(rand, &x,&y);
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01() > m_Contrast * pow(alpha, m_Pow))
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
helper.Out.x = m_Weight * SQR(alpha) * helper.In.x;
helper.Out.y = m_Weight * SQR(alpha) * helper.In.y;
}
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string contrast = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string pow = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi10 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phi20 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string gamma = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string delta = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x, y;\n"
<< "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius << ")\n"
<< "\t\t{\n"
<< "\t\t GlynnSim2Circle(&" << radius << ", &" << thickness << ", &" << phi10 << ", &" << delta << ", &" << gamma << ", mwc, &x,&y);\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * SQR(alpha) * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * SQR(alpha) * vIn.y;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual string OpenCLFuncsString()
{
return
"void GlynnSim2Circle(__constant real_t* radius, __constant real_t* thickness, __constant real_t* phi10, __constant real_t* delta, __constant real_t* gamma, uint2* mwc, real_t* x, real_t* y)\n"
"{\n"
" real_t r = *radius + *thickness - *gamma * MwcNext01(mwc);\n"
" real_t phi = *phi10 + *delta * MwcNext01(mwc);\n"
" real_t sinPhi = sin(phi);\n"
" real_t cosPhi = cos(phi);\n"
"\n"
" *x = r * cosPhi;\n"
" *y = r * sinPhi;\n"
"}\n"
"\n";
}
virtual void Precalc() override
{
m_Pow = fabs(m_Pow);
m_Phi10 = T(M_PI) * m_Phi1 / 180;
m_Phi20 = T(M_PI) * m_Phi2 / 180;
m_Gamma = m_Thickness * (2 * m_Radius + m_Thickness) / Zeps(m_Radius + m_Thickness);
m_Delta = m_Phi20 - m_Phi10;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Radius, prefix + "GlynnSim2_radius", 1));
m_Params.push_back(ParamWithName(&m_Thickness, prefix + "GlynnSim2_thickness", T(0.1), REAL, 0, 1));
m_Params.push_back(ParamWithName(&m_Contrast, prefix + "GlynnSim2_contrast", T(0.5), REAL, 0, 1));
m_Params.push_back(ParamWithName(&m_Pow, prefix + "GlynnSim2_pow", T(1.5)));
m_Params.push_back(ParamWithName(&m_Phi1, prefix + "GlynnSim2_Phi1"));
m_Params.push_back(ParamWithName(&m_Phi2, prefix + "GlynnSim2_Phi2", 360));
m_Params.push_back(ParamWithName(true, &m_Phi10, prefix + "GlynnSim2_Phi10"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Phi20, prefix + "GlynnSim2_Phi20"));
m_Params.push_back(ParamWithName(true, &m_Gamma, prefix + "GlynnSim2_Gamma"));
m_Params.push_back(ParamWithName(true, &m_Delta, prefix + "GlynnSim2_Delta"));
}
private:
void Circle(QTIsaac& rand, T* x, T* y)
{
T r = m_Radius + m_Thickness - m_Gamma * rand.Frand01();
T phi = m_Phi10 + m_Delta * rand.Frand01();
T sinPhi = sin(phi);
T cosPhi = cos(phi);
*x = r * cosPhi;
*y = r * sinPhi;
}
T m_Radius;//Params.
T m_Thickness;
T m_Contrast;
T m_Pow;
T m_Phi1;
T m_Phi2;
T m_Phi10;//Precalc.
T m_Phi20;
T m_Gamma;
T m_Delta;
};
///
/// GlynnSim3.
///
template
class EMBER_API GlynnSim3Variation : public ParametricVariation
{
public:
GlynnSim3Variation(T weight = 1.0) : ParametricVariation("GlynnSim3", VAR_GLYNNSIM3, weight, true, true)
{
Init();
}
PARVARCOPY(GlynnSim3Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x, y;
if (helper.m_PrecalcSqrtSumSquares < m_Radius1)
{
Circle(rand, &x,&y);
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01() > m_Contrast * pow(alpha, m_Pow))
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
helper.Out.x = m_Weight * SQR(alpha) * helper.In.x;
helper.Out.y = m_Weight * SQR(alpha) * helper.In.y;
}
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string thickness2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string contrast = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string pow = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string radius1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string radius2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string gamma = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x, y;\n"
<< "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius1 << ")\n"
<< "\t\t{\n"
<< "\t\t GlynnSim3Circle(&" << radius << ", &" << radius1 << ", &" << radius2 << ", &" << thickness << ", &" << gamma << ", mwc, &x,&y);\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * SQR(alpha) * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * SQR(alpha) * vIn.y;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual string OpenCLFuncsString()
{
return
"void GlynnSim3Circle(__constant real_t* radius, __constant real_t* radius1, __constant real_t* radius2, __constant real_t* thickness, __constant real_t* gamma, uint2* mwc, real_t* x, real_t* y)\n"
"{\n"
" real_t r = *radius + *thickness - *gamma * MwcNext01(mwc);\n"
" real_t phi = M_2PI * MwcNext01(mwc);\n"
" real_t sinPhi = sin(phi);\n"
" real_t cosPhi = cos(phi);\n"
"\n"
" if (MwcNext01(mwc) < *gamma)\n"
" r = *radius1;\n"
" else\n"
" r = *radius2;\n"
"\n"
" *x = r * cosPhi;\n"
" *y = r * sinPhi;\n"
"}\n"
"\n";
}
virtual void Precalc() override
{
m_Radius1 = m_Radius + m_Thickness;
m_Radius2 = SQR(m_Radius) / Zeps(m_Radius1);
m_Gamma = m_Radius1 / Zeps(m_Radius1 + m_Radius2);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Radius, prefix + "GlynnSim3_radius", 1));
m_Params.push_back(ParamWithName(&m_Thickness, prefix + "GlynnSim3_thickness", T(0.1)));
m_Params.push_back(ParamWithName(&m_Thickness2, prefix + "GlynnSim3_thickness2", T(0.1)));
m_Params.push_back(ParamWithName(&m_Contrast, prefix + "GlynnSim3_contrast", T(0.5), REAL, 0, 1));
m_Params.push_back(ParamWithName(&m_Pow, prefix + "GlynnSim3_pow", T(1.5)));
m_Params.push_back(ParamWithName(true, &m_Radius1, prefix + "GlynnSim3_radius1"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Radius2, prefix + "GlynnSim3_radius2"));
m_Params.push_back(ParamWithName(true, &m_Gamma, prefix + "GlynnSim3_Gamma"));
}
private:
void Circle(QTIsaac& rand, T* x, T* y)
{
T r = m_Radius + m_Thickness - m_Gamma * rand.Frand01();
T phi = M_2PI * rand.Frand01();
T sinPhi = sin(phi);
T cosPhi = cos(phi);
if (rand.Frand01() < m_Gamma)
r = m_Radius1;
else
r = m_Radius2;
*x = r * cosPhi;
*y = r * sinPhi;
}
T m_Radius;//Params.
T m_Thickness;
T m_Thickness2;
T m_Contrast;
T m_Pow;
T m_Radius1;//Precalc.
T m_Radius2;
T m_Gamma;
};
///
/// Starblur.
///
template
class EMBER_API StarblurVariation : public ParametricVariation
{
public:
StarblurVariation(T weight = 1.0) : ParametricVariation("starblur", VAR_STARBLUR, weight)
{
Init();
}
PARVARCOPY(StarblurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T f = rand.Frand01() * m_Power * 2;
T angle = T(int(f));
f -= angle;
T x = f * m_Length;
T z = sqrt(1 + SQR(x) - 2 * x * cos(m_Alpha));
if (int(angle) % 2)
angle = M_2PI / m_Power * (int(angle) / 2) + asin(sin(m_Alpha) * x / z);
else
angle = M_2PI / m_Power * (int(angle) / 2) - asin(sin(m_Alpha) * x / z);
z *= sqrt(rand.Frand01());
T temp = angle - T(M_PI_2);
helper.Out.x = m_Weight * z * cos(temp);
helper.Out.y = m_Weight * z * sin(temp);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string range = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string length = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string alpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t f = MwcNext01(mwc) * " << power << " * 2;\n"
<< "\t\treal_t angle = (real_t)(int)(f);\n"
<< "\n"
<< "\t\tf -= angle;\n"
<< "\n"
<< "\t\treal_t x = f * " << length << ";\n"
<< "\t\treal_t z = sqrt(1 + SQR(x) - 2 * x * cos(" << alpha << "));\n"
<< "\n"
<< "\t\tif (((int)angle) % 2)\n"
<< "\t\t angle = M_2PI / " << power << " * (((int)angle) / 2) + asin(sin(" << alpha << ") * x / z);\n"
<< "\t\telse\n"
<< "\t\t angle = M_2PI / " << power << " * (((int)angle) / 2) - asin(sin(" << alpha << ") * x / z);\n"
<< "\n"
<< "\t\tz *= sqrt(MwcNext01(mwc));\n"
<< "\n"
<< "\t\treal_t temp = angle - M_PI_2;\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * z * cos(temp);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * z * sin(temp);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Alpha = T(M_PI) / m_Power;
m_Length = sqrt(1 + SQR(m_Range) - 2 * m_Range * cos(m_Alpha));
m_Alpha = asin(sin(m_Alpha) * m_Range / m_Length);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Power, prefix + "starblur_power", 5, INTEGER_NONZERO));
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"));
}
private:
T m_Power;
T m_Range;
T m_Length;//Precalc.
T m_Alpha;
};
///
/// Sineblur.
///
template
class EMBER_API SineblurVariation : public ParametricVariation
{
public:
SineblurVariation(T weight = 1.0) : ParametricVariation("sineblur", VAR_SINEBLUR, weight)
{
Init();
}
PARVARCOPY(SineblurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T ang = rand.Frand01() * M_2PI;
T s = sin(ang);
T c = cos(ang);
T r = m_Weight * (m_Power == 1 ? acos(rand.Frand01() * 2 - 1) / T(M_PI) : acos(exp(log(rand.Frand01()) * m_Power) * 2 - 1) / T(M_PI));
helper.Out.x = r * c;
helper.Out.y = r * s;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t ang = MwcNext01(mwc) * M_2PI;\n"
<< "\t\treal_t s = sin(ang);\n"
<< "\t\treal_t c = cos(ang);\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * (" << power << " == 1 ? acos(MwcNext01(mwc) * 2 - 1) / M_PI : acos(exp(log(MwcNext01(mwc)) * " << power << ") * 2 - 1) / M_PI);\n"
<< "\n"
<< "\t\tvOut.x = r * c;\n"
<< "\t\tvOut.y = r * s;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Power, prefix + "sineblur_power", 1, REAL, 0));
}
private:
T m_Power;
};
///
/// Circleblur.
///
template
class EMBER_API CircleblurVariation : public Variation
{
public:
CircleblurVariation(T weight = 1.0) : Variation("circleblur", VAR_CIRCLEBLUR, weight) { }
VARCOPY(CircleblurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T rad = sqrt(rand.Frand01());
T temp = rand.Frand01() * M_2PI;
helper.Out.x = m_Weight * cos(temp) * rad;
helper.Out.y = m_Weight * sin(temp) * rad;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\treal_t rad = sqrt(MwcNext01(mwc));\n"
<< "\t\treal_t temp = MwcNext01(mwc) * M_2PI;\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cos(temp) * rad;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * sin(temp) * rad;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Depth.
///
template
class EMBER_API DepthVariation : public ParametricVariation
{
public:
DepthVariation(T weight = 1.0) : ParametricVariation("depth", VAR_DEPTH, weight)
{
Init();
}
PARVARCOPY(DepthVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T coeff = fabs(helper.In.z);
if (coeff != 0 && m_Power != 1)
coeff = exp(log(coeff) * m_Power);
helper.Out.x = m_Weight * (helper.m_TransX + helper.In.x * coeff);
helper.Out.y = m_Weight * (helper.m_TransY + helper.In.y * coeff);
helper.Out.z = m_Weight * (helper.m_TransZ + helper.In.z * coeff);
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t coeff = fabs(vIn.z);\n"
<< "\n"
<< "\t\tif (coeff != 0 && " << power << " != 1)\n"
<< "\t\t coeff = exp(log(coeff) * " << power << ");\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (transX + vIn.x * coeff);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (transY + vIn.y * coeff);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * (transZ + vIn.z * coeff);\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Power, prefix + "depth_power", 1));
}
private:
T m_Power;
};
///
/// CropN.
///
template
class EMBER_API CropNVariation : public ParametricVariation
{
public:
CropNVariation(T weight = 1.0) : ParametricVariation("cropn", VAR_CROPN, weight, true, true, false, false, true)
{
Init();
}
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 = 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 (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 * cos(helper.m_PrecalcAtanyx);
helper.Out.y = m_Weight * rdc * sin(helper.m_PrecalcAtanyx);
}
}
else
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string scatterDist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
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;
ss << "\t{\n"
<< "\t\treal_t xang = (precalcAtanyx + M_PI) / " << 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 = xr + (MwcNext01(mwc) * (real_t)(0.5) * " << scatterDist << ");\n"
<< "\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * rdc * cos(precalcAtanyx);\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * rdc * sin(precalcAtanyx);\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
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;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
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, INTEGER, 0, 1));
m_Params.push_back(ParamWithName(true, &m_WorkPower, prefix + "cropn_workpower"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "cropn_alpha"));
}
private:
T m_Power;
T m_Radius;
T m_ScatterDist;
T m_Zero;
T m_WorkPower;//Precalc.
T m_Alpha;
};
///
/// ShredRad.
///
template
class EMBER_API ShredRadVariation : public ParametricVariation
{
public:
ShredRadVariation(T weight = 1.0) : ParametricVariation("shredrad", VAR_SHRED_RAD, weight, true, true, false, false, true)
{
Init();
}
PARVARCOPY(ShredRadVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T xang = (helper.m_PrecalcAtanyx + M_3PI + m_Alpha / 2) / m_Alpha;
T zang = ((xang - int(xang)) * m_Width + int(xang)) * m_Alpha - T(M_PI) - m_Alpha / 2 * m_Width;
helper.Out.x = m_Weight * helper.m_PrecalcSqrtSumSquares * cos(zang);
helper.Out.y = m_Weight * helper.m_PrecalcSqrtSumSquares * sin(zang);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string width = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string alpha = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t xang = (precalcAtanyx + M_3PI + " << alpha << " / 2) / " << alpha << ";\n"
<< "\t\treal_t zang = ((xang - (int)xang) * " << width << " + (int)xang) * " << alpha << " - M_PI - " << alpha << " / 2 * " << width << ";\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares * cos(zang);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares * sin(zang);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Alpha = M_2PI / m_N;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "shredrad_n", 4, REAL_NONZERO));
m_Params.push_back(ParamWithName(&m_Width, prefix + "shredrad_width", T(0.5), REAL, -1, 1));
m_Params.push_back(ParamWithName(true, &m_Alpha, prefix + "shredrad_alpha"));//Precalc.
}
private:
T m_N;
T m_Width;
T m_Alpha;//Precalc.
};
///
/// Blob2.
///
template
class EMBER_API Blob2Variation : public ParametricVariation
{
public:
Blob2Variation(T weight = 1.0) : ParametricVariation("blob2", VAR_BLOB2, weight, true, true, false, false, true)
{
Init();
}
PARVARCOPY(Blob2Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (helper.m_PrecalcSqrtSumSquares < m_Radius)
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
T delta = (sin(helper.m_PrecalcAtanyx * m_N) + m_Symmetry) / m_DeltaHelp;
T positive = 1 - T(delta < 0 ? 1 : 0) * 2;
if (m_Mode != 0)
delta = exp(m_Prescale * log(delta * positive)) * m_Postscale * m_Mode;
else
delta = exp(m_Prescale * log(delta * positive)) * m_Postscale * positive;
T rad = m_Radius + (helper.m_PrecalcSqrtSumSquares - m_Radius) * delta;
helper.Out.x = m_Weight * rad * cos(helper.m_PrecalcAtanyx);
helper.Out.y = m_Weight * rad * sin(helper.m_PrecalcAtanyx);
helper.Out.z = m_Weight * helper.In.z;
//helper.m_TransZ += m_Weight * outPoint.m_Z;//Original had this which is probably wrong.
}
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string mode = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string prescale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string postscale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string symmetry = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string comp = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string dataHelp = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius << ")\n"
<< "\t\t{\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t real_t delta = (sin(precalcAtanyx * " << n << ") + " << symmetry << ") / " << dataHelp << ";\n"
<< "\t\t real_t positive = 1 - (real_t)(delta < 0 ? 1 : 0) * 2;\n"
<< "\n"
<< "\t\t if (" << mode << " != 0)\n"
<< "\t\t delta = exp(" << prescale << " * log(delta * positive)) * " << postscale << " * " << mode << ";\n"
<< "\t\t else\n"
<< "\t\t delta = exp(" << prescale << " * log(delta * positive)) * " << postscale << " * positive;\n"
<< "\n"
<< "\t\t real_t rad = " << radius << " + (precalcSqrtSumSquares - " << radius << ") * delta;\n"
<< "\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * rad * cos(precalcAtanyx);\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * rad * sin(precalcAtanyx);\n"
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
//<< "\t\t transZ += xform->m_VariationWeights[" << varIndex << "] * outPoint->m_Z;\n"//Original had this which is probably wrong.
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_DeltaHelp = 1 + m_Compensation * m_Symmetry * (1 - (m_Symmetry < 0) * 2);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Mode, prefix + "blob2_mode", 0, INTEGER, -1, 1));
m_Params.push_back(ParamWithName(&m_N, prefix + "blob2_n", 5, INTEGER));
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, REAL, -1, 1));
m_Params.push_back(ParamWithName(&m_Compensation, prefix + "blob2_compensation", 0, REAL, 0, 1));
m_Params.push_back(ParamWithName(true, &m_DeltaHelp, prefix + "blob2_deltahelp"));//Precalc.
}
private:
T m_Mode;
T m_N;
T m_Radius;
T m_Prescale;
T m_Postscale;
T m_Symmetry;
T m_Compensation;
T m_DeltaHelp;//Precalc.
};
///
/// Julia3D.
///
template
class EMBER_API Julia3DVariation : public ParametricVariation
{
public:
Julia3DVariation(T weight = 1.0) : ParametricVariation("julia3D", VAR_JULIA3D, weight, true, true, false, false, true)
{
Init();
}
PARVARCOPY(Julia3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T z = helper.In.z / m_AbsN;
T r = m_Weight * pow(helper.m_PrecalcSumSquares + SQR(z), m_Cn);
T tmp = r * helper.m_PrecalcSqrtSumSquares;
T ang = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(uint(m_AbsN))) / m_N;
helper.Out.x = tmp * cos(ang);
helper.Out.y = tmp * sin(ang);
helper.Out.z = r * z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string n = "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 z = vIn.z / " << absn << ";\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares + SQR(z), " << cn << ");\n"
<< "\t\treal_t tmp = r * precalcSqrtSumSquares;\n"
<< "\t\treal_t ang = (precalcAtanyx + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << n << ";\n"
<< "\n"
<< "\t\tvOut.x = tmp * cos(ang);\n"
<< "\t\tvOut.y = tmp * sin(ang);\n"
<< "\t\tvOut.z = r * z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_AbsN = fabs(m_N);
m_Cn = (1 / m_N - 1) / 2;
}
virtual void Random(QTIsaac& rand) override
{
m_N = T(rand.Rand(5) + 2);
if (rand.Rand(2) == 0)
m_N = -m_N;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "julia3D_power", 2, INTEGER_NONZERO));
m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "julia3D_absn"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "julia3D_cn"));
}
private:
T m_N;
T m_AbsN;//Precalc.
T m_Cn;
};
///
/// Julia3Dz.
///
template
class EMBER_API Julia3DzVariation : public ParametricVariation
{
public:
Julia3DzVariation(T weight = 1.0) : ParametricVariation("julia3Dz", VAR_JULIA3DZ, weight, true, true, false, false, true)
{
Init();
}
PARVARCOPY(Julia3DzVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn);
T temp = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(uint(m_AbsN))) / m_N;
helper.Out.x = r * cos(temp);
helper.Out.y = r * sin(temp);
helper.Out.z = r * helper.In.z / (helper.m_PrecalcSqrtSumSquares * m_AbsN);
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string n = "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 r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << ");\n"
<< "\t\treal_t temp = (precalcAtanyx + M_2PI * MwcNextRange(mwc, (uint)" << absn << ")) / " << n << ";\n"
<< "\n"
<< "\t\tvOut.x = r * cos(temp);\n"
<< "\t\tvOut.y = r * sin(temp);\n"
<< "\t\tvOut.z = r * vIn.z / (precalcSqrtSumSquares * " << absn << ");\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_AbsN = fabs(m_N);
m_Cn = 1 / m_N / 2;
}
virtual void Random(QTIsaac& rand) override
{
m_N = T(rand.Rand(5) + 2);
if (rand.Rand(2) == 0)
m_N = -m_N;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "julia3Dz_power", 2, INTEGER_NONZERO));
m_Params.push_back(ParamWithName(true, &m_AbsN, prefix + "julia3Dz_absn"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "julia3Dz_cn"));
}
private:
T m_N;
T m_AbsN;//Precalc.
T m_Cn;
};
///
/// LinearT.
///
template
class EMBER_API LinearTVariation : public ParametricVariation
{
public:
LinearTVariation(T weight = 1.0) : ParametricVariation("linearT", VAR_LINEAR_T, weight)
{
Init();
}
PARVARCOPY(LinearTVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = SignNz(helper.In.x) * pow(fabs(helper.In.x), m_PowX) * m_Weight;
helper.Out.y = SignNz(helper.In.y) * pow(fabs(helper.In.y), m_PowY) * m_Weight;
helper.Out.z = (m_VarType == VARTYPE_REG) ? 0 : helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string powx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string powy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tvOut.x = SignNz(vIn.x) * pow(fabs(vIn.x), " << powx << ") * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.y = SignNz(vIn.y) * pow(fabs(vIn.y), " << powy << ") * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.z = " << ((m_VarType == VARTYPE_REG) ? "0" : "vIn.z") << ";\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_PowX, prefix + "linearT_powX", 1));//Original used a prefix of lT, which is incompatible with Ember's design.
m_Params.push_back(ParamWithName(&m_PowY, prefix + "linearT_powY", 1));
}
private:
T m_PowX;
T m_PowY;
};
///
/// LinearT3D.
///
template
class EMBER_API LinearT3DVariation : public ParametricVariation
{
public:
LinearT3DVariation(T weight = 1.0) : ParametricVariation("linearT3D", VAR_LINEAR_T3D, weight)
{
Init();
}
PARVARCOPY(LinearT3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = T(helper.In.x < 0 ? -1 : 1) * pow(fabs(helper.In.x), m_PowX) * m_Weight;
helper.Out.y = T(helper.In.y < 0 ? -1 : 1) * pow(fabs(helper.In.y), m_PowY) * m_Weight;
helper.Out.z = T(helper.In.z < 0 ? -1 : 1) * pow(fabs(helper.In.z), m_PowZ) * m_Weight;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string powx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string powy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string powz = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tvOut.x = (real_t)(vIn.x < 0 ? -1 : 1) * pow(fabs(vIn.x), " << powx << ") * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.y = (real_t)(vIn.y < 0 ? -1 : 1) * pow(fabs(vIn.y), " << powy << ") * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t\tvOut.z = (real_t)(vIn.z < 0 ? -1 : 1) * pow(fabs(vIn.z), " << powz << ") * xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_PowX, prefix + "linearT3D_powX", 1));
m_Params.push_back(ParamWithName(&m_PowY, prefix + "linearT3D_powY", 1));
m_Params.push_back(ParamWithName(&m_PowZ, prefix + "linearT3D_powZ", 1));
}
private:
T m_PowX;
T m_PowY;
T m_PowZ;
};
///
/// Ovoid.
///
template
class EMBER_API OvoidVariation : public ParametricVariation
{
public:
OvoidVariation(T weight = 1.0) : ParametricVariation("ovoid", VAR_OVOID, weight, true)
{
Init();
}
PARVARCOPY(OvoidVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_Weight / Zeps(helper.m_PrecalcSumSquares);
helper.Out.x = helper.In.x * r * m_X;
helper.Out.y = helper.In.y * r * m_Y;
helper.Out.z = (m_VarType == VARTYPE_REG) ? 0 : helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / Zeps(precalcSumSquares);\n"
<< "\n"
<< "\t\tvOut.x = vIn.x * r * " << x << ";\n"
<< "\t\tvOut.y = vIn.y * r * " << y << ";\n"
<< "\t\tvOut.z = " << ((m_VarType == VARTYPE_REG) ? "0" : "vIn.z") << ";\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X, prefix + "ovoid_x", 1));
m_Params.push_back(ParamWithName(&m_Y, prefix + "ovoid_y", 1));
}
private:
T m_X;
T m_Y;
};
///
/// Ovoid3D.
///
template
class EMBER_API Ovoid3DVariation : public ParametricVariation
{
public:
Ovoid3DVariation(T weight = 1.0) : ParametricVariation("ovoid3d", VAR_OVOID3D, weight, true)
{
Init();
}
PARVARCOPY(Ovoid3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_Weight / Zeps(helper.m_PrecalcSumSquares + SQR(helper.In.z));
helper.Out.x = helper.In.x * r * m_X;
helper.Out.y = helper.In.y * r * m_Y;
helper.Out.z = helper.In.z * r * m_Z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string z = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / Zeps(precalcSumSquares + SQR(vIn.z));\n"
<< "\n"
<< "\t\tvOut.x = vIn.x * r * " << x << ";\n"
<< "\t\tvOut.y = vIn.y * r * " << y << ";\n"
<< "\t\tvOut.z = vIn.z * r * " << z << ";\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X, prefix + "ovoid3d_x", 1));
m_Params.push_back(ParamWithName(&m_Y, prefix + "ovoid3d_y", 1));
m_Params.push_back(ParamWithName(&m_Z, prefix + "ovoid3d_z", 1));
}
private:
T m_X;
T m_Y;
T m_Z;
};
///