#pragma once
#include "Variation.h"
namespace EmberNs
{
///
/// Hemisphere.
///
template
class EMBER_API HemisphereVariation : public Variation
{
public:
HemisphereVariation(T weight = 1.0) : Variation("hemisphere", VAR_HEMISPHERE, weight, true) { }
VARCOPY(HemisphereVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T t = m_Weight / sqrt(helper.m_PrecalcSumSquares + 1);
helper.Out.x = helper.In.x * t;
helper.Out.y = helper.In.y * t;
helper.Out.z = t;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\treal_t t = xform->m_VariationWeights[" << varIndex << "] / sqrt(precalcSumSquares + 1.0);\n"
<< "\n"
<< "\t\tvOut.x = vIn.x * t;\n"
<< "\t\tvOut.y = vIn.y * t;\n"
<< "\t\tvOut.z = t;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Epispiral.
///
template
class EMBER_API EpispiralVariation : public ParametricVariation
{
public:
EpispiralVariation(T weight = 1.0) : ParametricVariation("epispiral", VAR_EPISPIRAL, weight, false, false, false, false, true)
{
Init();
}
PARVARCOPY(EpispiralVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T theta = helper.m_PrecalcAtanyx;
T t = (rand.Frand01() * m_Thickness) * (1 / cos(m_N * theta)) - m_Holes;
if (fabs(t) != 0)
{
helper.Out.x = m_Weight * t * cos(theta);
helper.Out.y = m_Weight * t * sin(theta);
helper.Out.z = 0;
}
else
{
helper.Out.x = 0;
helper.Out.y = 0;
helper.Out.z = 0;
}
}
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 thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string holes = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t theta = precalcAtanyx;\n"
<< "\t\treal_t t = (MwcNext01(mwc) * " << thickness << ") * (1 / cos(" << n << " * theta)) - " << holes << ";\n"
<< "\n"
<< "\t\tif (fabs(t) != 0)\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * t * cos(theta);\n"
<< "\t\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * t * sin(theta);\n"
<< "\t\t\tvOut.z = 0;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = 0;\n"
<< "\t\t\tvOut.y = 0;\n"
<< "\t\t\tvOut.z = 0;\n"
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_N, prefix + "epispiral_n", 6));
m_Params.push_back(ParamWithName(&m_Thickness, prefix + "epispiral_thickness"));
m_Params.push_back(ParamWithName(&m_Holes, prefix + "epispiral_holes", 1));
}
private:
T m_N;
T m_Thickness;
T m_Holes;
};
///
/// Bwraps.
/// Note, this is the same as bwraps2.
///
template
class EMBER_API BwrapsVariation : public ParametricVariation
{
public:
BwrapsVariation(T weight = 1.0) : ParametricVariation("bwraps", VAR_BWRAPS, weight)
{
Init();
}
PARVARCOPY(BwrapsVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_BwrapsCellsize == 0)
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
T vx = helper.In.x;
T vy = helper.In.y;
T cx = (Floor(vx / m_BwrapsCellsize) + T(0.5)) * m_BwrapsCellsize;
T cy = (Floor(vy / m_BwrapsCellsize) + T(0.5)) * m_BwrapsCellsize;
T lx = vx - cx;
T ly = vy - cy;
if ((SQR(lx) + SQR(ly)) > m_R2)
{
helper.Out.x = m_Weight * helper.In.x;
helper.Out.y = m_Weight * helper.In.y;
}
else
{
lx *= m_G2;
ly *= m_G2;
T r = m_Rfactor / ((SQR(lx) + SQR(ly)) / 4 + 1);
lx *= r;
ly *= r;
r = (SQR(lx) + SQR(ly)) / m_R2;
T theta = m_BwrapsInnerTwist * (1 - r) + m_BwrapsOuterTwist * r;
T s = sin(theta);
T c = cos(theta);
vx = cx + c * lx + s * ly;
vy = cy - s * lx + c * ly;
helper.Out.x = m_Weight * vx;
helper.Out.y = m_Weight * vy;
}
}
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string bwrapsCellsize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsSpace = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsGain = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsInnerTwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bwrapsOuterTwist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string g2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string r2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rfactor = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif (" << bwrapsCellsize << " == 0)\n"
<< "\t\t{\n"
<< "\t\t vOut.x = 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 vx = vIn.x;\n"
<< "\t\t real_t vy = vIn.y;\n"
<< "\t\t real_t cx = (floor(vx / " << bwrapsCellsize << ") + 0.5) * " << bwrapsCellsize << ";\n"
<< "\t\t real_t cy = (floor(vy / " << bwrapsCellsize << ") + 0.5) * " << bwrapsCellsize << ";\n"
<< "\t\t real_t lx = vx - cx;\n"
<< "\t\t real_t ly = vy - cy;\n"
<< "\n"
<< "\t\t if ((SQR(lx) + SQR(ly)) > " << r2 << ")\n"
<< "\t\t {\n"
<< "\t\t vOut.x = 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 lx *= " << g2 << ";\n"
<< "\t\t ly *= " << g2 << ";\n"
<< "\n"
<< "\t\t real_t r = " << rfactor << " / ((SQR(lx) + SQR(ly)) / 4 + 1);\n"
<< "\n"
<< "\t\t lx *= r;\n"
<< "\t\t ly *= r;\n"
<< "\t\t r = (SQR(lx) + SQR(ly)) / " << r2 << ";\n"
<< "\n"
<< "\t\t real_t theta = " << bwrapsInnerTwist << " * (1 - r) + " << bwrapsOuterTwist << " * r;\n"
<< "\t\t real_t s = sin(theta);\n"
<< "\t\t real_t c = cos(theta);\n"
<< "\n"
<< "\t\t vx = cx + c * lx + s * ly;\n"
<< "\t\t vy = cy - s * lx + c * ly;\n"
<< "\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vx;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vy;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
T radius = T(0.5) * (m_BwrapsCellsize / (1 + SQR(m_BwrapsSpace)));
m_G2 = Zeps(SQR(m_BwrapsGain) / Zeps(radius));
T maxBubble = m_G2 * radius;
if (maxBubble > 2)
maxBubble = 1;
else
maxBubble *= (1 / (SQR(maxBubble) / 4 + 1));
m_R2 = SQR(radius);
m_Rfactor = radius / maxBubble;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BwrapsCellsize, prefix + "bwraps_cellsize", 1));
m_Params.push_back(ParamWithName(&m_BwrapsSpace, prefix + "bwraps_space"));
m_Params.push_back(ParamWithName(&m_BwrapsGain, prefix + "bwraps_gain", 1));
m_Params.push_back(ParamWithName(&m_BwrapsInnerTwist, prefix + "bwraps_inner_twist"));
m_Params.push_back(ParamWithName(&m_BwrapsOuterTwist, prefix + "bwraps_outer_twist"));
m_Params.push_back(ParamWithName(true, &m_G2, prefix + "bwraps_g2"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_R2, prefix + "bwraps_r2"));
m_Params.push_back(ParamWithName(true, &m_Rfactor, prefix + "bwraps_rfactor"));
}
private:
T m_BwrapsCellsize;
T m_BwrapsSpace;
T m_BwrapsGain;
T m_BwrapsInnerTwist;
T m_BwrapsOuterTwist;
T m_G2;//Precalc.
T m_R2;
T m_Rfactor;
};
///
/// BlurCircle.
///
template
class EMBER_API BlurCircleVariation : public Variation
{
public:
BlurCircleVariation(T weight = 1.0) : Variation("blur_circle", VAR_BLUR_CIRCLE, weight) { }
VARCOPY(BlurCircleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = 2 * rand.Frand01() - 1;
T y = 2 * rand.Frand01() - 1;
T absx = x;
T absy = y;
T side, perimeter;
if (absx < 0)
absx = absx * -1;
if (absy < 0)
absy = absy * -1;
if (absx >= absy)
{
if (x >= absy)
perimeter = absx + y;
else
perimeter = 5 * absx - y;
side = absx;
}
else
{
if (y >= absx)
perimeter = 3 * absy - x;
else
perimeter = 7 * absy + x;
side = absy;
}
T r = m_Weight * side;
T val = T(M_PI_4) * perimeter / side - T(M_PI_4);
T sina = sin(val);
T cosa = cos(val);
helper.Out.x = r * cosa;
helper.Out.y = r * sina;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
ss << "\t{\n"
<< "\t\treal_t x = 2 * MwcNext01(mwc) - 1;\n"
<< "\t\treal_t y = 2 * MwcNext01(mwc) - 1;\n"
<< "\t\treal_t absx = x;\n"
<< "\t\treal_t absy = y;\n"
<< "\t\treal_t side, perimeter;\n"
<< "\t\t\n"
<< "\t\tif (absx < 0)\n"
<< "\t\t absx = absx * -1;\n"
<< "\n"
<< "\t\tif (absy < 0)\n"
<< "\t\t absy = absy * -1;\n"
<< "\n"
<< "\t\tif (absx >= absy)\n"
<< "\t\t{\n"
<< "\t\t if (x >= absy)\n"
<< "\t\t perimeter = absx + y;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 5 * absx - y;\n"
<< "\n"
<< "\t\t side = absx;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (y >= absx)\n"
<< "\t\t perimeter = 3 * absy - x;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 7 * absy + x;\n"
<< "\n"
<< "\t\t side = absy;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * side;\n"
<< "\t\treal_t val = M_PI_4 * perimeter / side - M_PI_4;\n"
<< "\t\treal_t sina = sin(val);\n"
<< "\t\treal_t cosa = cos(val);\n"
<< "\n"
<< "\t\tvOut.x = r * cosa;\n"
<< "\t\tvOut.y = r * sina;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// BlurZoom.
///
template
class EMBER_API BlurZoomVariation : public ParametricVariation
{
public:
BlurZoomVariation(T weight = 1.0) : ParametricVariation("blur_zoom", VAR_BLUR_ZOOM, weight)
{
Init();
}
PARVARCOPY(BlurZoomVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T z = 1 + m_BlurZoomLength * rand.Frand01();
helper.Out.x = m_Weight * ((helper.In.x - m_BlurZoomX) * z + m_BlurZoomX);
helper.Out.y = m_Weight * ((helper.In.y - m_BlurZoomY) * z - m_BlurZoomY);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string blurZoomLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurZoomX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurZoomY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t z = 1 + " << blurZoomLength << " * MwcNext01(mwc);\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * ((vIn.x - " << blurZoomX << ") * z + " << blurZoomX << ");\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * ((vIn.y - " << blurZoomY << ") * z - " << blurZoomY << ");\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_BlurZoomLength, prefix + "blur_zoom_length"));
m_Params.push_back(ParamWithName(&m_BlurZoomX, prefix + "blur_zoom_x"));
m_Params.push_back(ParamWithName(&m_BlurZoomY, prefix + "blur_zoom_y"));
}
private:
T m_BlurZoomLength;
T m_BlurZoomX;
T m_BlurZoomY;
};
///
/// BlurPixelize.
///
template
class EMBER_API BlurPixelizeVariation : public ParametricVariation
{
public:
BlurPixelizeVariation(T weight = 1.0) : ParametricVariation("blur_pixelize", VAR_BLUR_PIXELIZE, weight)
{
Init();
}
PARVARCOPY(BlurPixelizeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = T(Floor(helper.In.x * m_InvSize));
T y = T(Floor(helper.In.y * m_InvSize));
helper.Out.x = m_V * (x + m_BlurPixelizeScale * (rand.Frand01() - T(0.5)) + T(0.5));
helper.Out.y = m_V * (y + m_BlurPixelizeScale * (rand.Frand01() - T(0.5)) + T(0.5));
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string blurPixelizeSize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurPixelizeScale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string v = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string invSize = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = floor(vIn.x * " << invSize << ");\n"
<< "\t\treal_t y = floor(vIn.y * " << invSize << ");\n"
<< "\n"
<< "\t\tvOut.x = " << v << " * (x + " << blurPixelizeScale << " * (MwcNext01(mwc) - 0.5) + 0.5);\n"
<< "\t\tvOut.y = " << v << " * (y + " << blurPixelizeScale << " * (MwcNext01(mwc) - 0.5) + 0.5);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_V = m_Weight * m_BlurPixelizeSize;
m_InvSize = 1 / m_BlurPixelizeSize;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BlurPixelizeSize, prefix + "blur_pixelize_size", T(0.1), REAL, EPS));
m_Params.push_back(ParamWithName(&m_BlurPixelizeScale, prefix + "blur_pixelize_scale", 1));
m_Params.push_back(ParamWithName(true, &m_V, prefix + "blur_pixelize_v"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_InvSize, prefix + "blur_pixelize_inv_size"));
}
private:
T m_BlurPixelizeSize;
T m_BlurPixelizeScale;
T m_V;//Precalc.
T m_InvSize;
};
///
/// Crop.
///
template
class EMBER_API CropVariation : public ParametricVariation
{
public:
CropVariation(T weight = 1.0) : ParametricVariation("crop", VAR_CROP, weight)
{
Init();
}
PARVARCOPY(CropVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = helper.In.x;
T y = helper.In.y;
if (((x < m_X0_) || (x > m_X1_) || (y < m_Y0_) || (y > m_Y1_)) && m_Z != 0)
{
x = 0;
y = 0;
}
else
{
if (x < m_X0_)
x = m_X0_ + rand.Frand01() * m_W;
else if (x > m_X1_)
x = m_X1_ - rand.Frand01() * m_W;
if (y < m_Y0_)
y = m_Y0_ + rand.Frand01() * m_H;
else if (y > m_Y1_)
y = m_Y1_ - rand.Frand01() * m_H;
}
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string x0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string z = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x0_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y0_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string x1_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string y1_ = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string w = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string h = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = vIn.x;\n"
<< "\t\treal_t y = vIn.y;\n"
<< "\n"
<< "\t\tif (((x < " << x0_ << ") || (x > " << x1_ << ") || (y < " << y0_ << ") || (y > " << y1_ << ")) && " << z << " != 0)\n"
<< "\t\t{\n"
<< "\t\t x = 0;\n"
<< "\t\t y = 0;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (x < " << x0_ << ")\n"
<< "\t\t x = " << x0_ << " + MwcNext01(mwc) * " << w << ";\n"
<< "\t\t else if (x > " << x1_ << ")\n"
<< "\t\t x = " << x1_ << " - MwcNext01(mwc) * " << w << ";\n"
<< "\t\t\n"
<< "\t\t if (y < " << y0_ << ")\n"
<< "\t\t y = " << y0_ << " + MwcNext01(mwc) * " << h << ";\n"
<< "\t\t else if (y > " << y1_ << ")\n"
<< "\t\t y = " << y1_ << " - MwcNext01(mwc) * " << h << ";\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
if (m_X0 < m_X1)
{
m_X0_ = m_X0;
m_X1_ = m_X1;
}
else
{
m_X0_ = m_X1;
m_X1_ = m_X0;
}
if (m_Y0 < m_Y1)
{
m_Y0_ = m_Y0;
m_Y1_ = m_Y1;
}
else
{
m_Y0_ = m_Y1;
m_Y1_ = m_Y0;
}
m_W = (m_X1_ - m_X0_) * T(0.5) * m_S;
m_H = (m_Y1_ - m_Y0_) * T(0.5) * m_S;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X0, prefix + "crop_left", -1));
m_Params.push_back(ParamWithName(&m_Y0, prefix + "crop_top", -1));
m_Params.push_back(ParamWithName(&m_X1, prefix + "crop_right", 1));
m_Params.push_back(ParamWithName(&m_Y1, prefix + "crop_bottom", 1));
m_Params.push_back(ParamWithName(&m_S, prefix + "crop_scatter_area", 0, REAL, -1, 1));
m_Params.push_back(ParamWithName(&m_Z, prefix + "crop_zero", 0, INTEGER, 0, 1));
m_Params.push_back(ParamWithName(true, &m_X0_, prefix + "crop_x0_"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Y0_, prefix + "crop_y0_"));
m_Params.push_back(ParamWithName(true, &m_X1_, prefix + "crop_x1_"));
m_Params.push_back(ParamWithName(true, &m_Y1_, prefix + "crop_y1_"));
m_Params.push_back(ParamWithName(true, &m_W, prefix + "crop_w"));
m_Params.push_back(ParamWithName(true, &m_H, prefix + "crop_h"));
}
private:
T m_X0;
T m_Y0;
T m_X1;
T m_Y1;
T m_S;
T m_Z;
T m_X0_;//Precalc.
T m_Y0_;
T m_X1_;
T m_Y1_;
T m_W;
T m_H;
};
///
/// BCircle.
///
template
class EMBER_API BCircleVariation : public ParametricVariation
{
public:
BCircleVariation(T weight = 1.0) : ParametricVariation("bcircle", VAR_BCIRCLE, weight)
{
Init();
}
PARVARCOPY(BCircleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if ((helper.In.x == 0) && (helper.In.y == 0))
return;
T x = helper.In.x * m_Scale;
T y = helper.In.y * m_Scale;
T r = sqrt(SQR(x) + SQR(y));
if (r <= 1)
{
helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y;
}
else
{
if (m_Bcbw != 0)
{
T ang = atan2(y, x);
T omega = (T(0.2) * m_Bcbw * rand.Frand01()) + 1;
T px = omega * cos(ang);
T py = omega * sin(ang);
helper.Out.x = m_Weight * px;
helper.Out.y = m_Weight * py;
}
}
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 scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string borderWidth = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string bcbw = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\tif ((vIn.x == 0) && (vIn.y == 0))\n"
<< "\t\t return;\n"
<< "\n"
<< "\t\treal_t x = vIn.x * " << scale << ";\n"
<< "\t\treal_t y = vIn.y * " << scale << ";\n"
<< "\t\treal_t r = sqrt(SQR(x) + SQR(y));\n"
<< "\n"
<< "\t\tif (r <= 1)\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\telse\n"
<< "\t\t{\n"
<< "\t\t if (" << bcbw << " != 0)\n"
<< "\t\t {\n"
<< "\t\t real_t ang = atan2(y, x);\n"
<< "\t\t real_t omega = (0.2 * " << bcbw << " * MwcNext01(mwc)) + 1;\n"
<< "\t\t real_t px = omega * cos(ang);\n"
<< "\t\t real_t py = omega * sin(ang);\n"
<< "\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * px;\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * py;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Bcbw = fabs(m_BorderWidth);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Scale, prefix + "bcircle_scale", 1));
m_Params.push_back(ParamWithName(&m_BorderWidth, prefix + "bcircle_borderwidth"));
m_Params.push_back(ParamWithName(true, &m_Bcbw, prefix + "bcircle_bcbw"));//Precalc.
}
private:
T m_Scale;
T m_BorderWidth;
T m_Bcbw;//Precalc.
};
///
/// BlurLinear.
///
template
class EMBER_API BlurLinearVariation : public ParametricVariation
{
public:
BlurLinearVariation(T weight = 1.0) : ParametricVariation("blur_linear", VAR_BLUR_LINEAR, weight)
{
Init();
}
PARVARCOPY(BlurLinearVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_BlurLinearLength * rand.Frand01();
helper.Out.x = m_Weight * (helper.In.x + r * m_C);
helper.Out.y = m_Weight * (helper.In.y + r * m_S);
helper.Out.z = 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 blurLinearLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blurLinearAngle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = " << blurLinearLength << " * MwcNext01(mwc);\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + r * " << c << ");\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + r * " << s << ");\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
sincos(m_BlurLinearAngle, &m_S, &m_C);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_BlurLinearLength, prefix + "blur_linear_length"));
m_Params.push_back(ParamWithName(&m_BlurLinearAngle, prefix + "blur_linear_angle", 0, REAL_CYCLIC, 0, T(M_2PI)));
m_Params.push_back(ParamWithName(true, &m_S, prefix + "blur_linear_s"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_C, prefix + "blur_linear_c"));
}
private:
T m_BlurLinearLength;
T m_BlurLinearAngle;
T m_S;//Precalc.
T m_C;
};
///
/// BlurSquare.
///
template
class EMBER_API BlurSquareVariation : public ParametricVariation
{
public:
BlurSquareVariation(T weight = 1.0) : ParametricVariation("blur_square", VAR_BLUR_SQUARE, weight)
{
Init();
}
PARVARCOPY(BlurSquareVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = m_V * (rand.Frand01() - T(0.5));
helper.Out.y = m_V * (rand.Frand01() - T(0.5));
helper.Out.z = 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 v = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params.
ss << "\t{\n"
<< "\t\tvOut.x = " << v << " * (MwcNext01(mwc) - 0.5);\n"
<< "\t\tvOut.y = " << v << " * (MwcNext01(mwc) - 0.5);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_V = m_Weight * 2;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(true, &m_V, prefix + "blur_square_v"));//Precalcs only, no params.
}
private:
T m_V;
};
///
/// Flatten.
/// This uses in/out in a rare and different way.
///
template
class EMBER_API FlattenVariation : public Variation
{
public:
FlattenVariation(T weight = 1.0) : Variation("flatten", VAR_FLATTEN, weight) { }
VARCOPY(FlattenVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == VARTYPE_REG)//Rare and different usage of in/out.
{
helper.Out.x = helper.Out.y = helper.Out.z = 0;
outPoint.m_Z = 0;
}
else
{
helper.Out.x = helper.In.x;
helper.Out.y = helper.In.y;
helper.Out.z = 0;
}
}
virtual string OpenCLString() override
{
ostringstream ss;
if (m_VarType == VARTYPE_REG)
{
ss << "\t{\n"
<< "\t\tvOut.x = 0;\n"
<< "\t\tvOut.y = 0;\n"
<< "\t\tvOut.z = 0;\n"
<< "\t\toutPoint->m_Z = 0;\n"
<< "\t}\n";
}
else
{
ss << "\t{\n"
<< "\t\tvOut.x = vIn.x;\n"
<< "\t\tvOut.y = vIn.y;\n"
<< "\t\tvOut.z = 0;\n"
<< "\t}\n";
}
return ss.str();
}
};
///
/// Zblur.
/// This uses in/out in a rare and different way.
///
template
class EMBER_API ZblurVariation : public Variation
{
public:
ZblurVariation(T weight = 1.0) : Variation("zblur", VAR_ZBLUR, weight) { }
VARCOPY(ZblurVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2);
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) - 2.0);\n"
<< "\t}\n";
return ss.str();
}
};
///
/// ZScale.
/// This uses in/out in a rare and different way.
///
template
class EMBER_API ZScaleVariation : public Variation
{
public:
ZScaleVariation(T weight = 1.0) : Variation("zscale", VAR_ZSCALE, weight) { }
VARCOPY(ZScaleVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// ZTranslate.
/// This uses in/out in a rare and different way.
///
template
class EMBER_API ZTranslateVariation : public Variation
{
public:
ZTranslateVariation(T weight = 1.0) : Variation("ztranslate", VAR_ZTRANSLATE, weight) { }
VARCOPY(ZTranslateVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
helper.Out.x = helper.Out.y = 0;
helper.Out.z = m_Weight;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\tvOut.x = vOut.y = 0;\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "];\n"
<< "\t}\n";
return ss.str();
}
};
///
/// zcone.
/// This uses in/out in a rare and different way.
///
template
class EMBER_API ZConeVariation : public Variation
{
public:
ZConeVariation(T weight = 1.0) : Variation("zcone", VAR_ZCONE, weight, true, true) { }
VARCOPY(ZConeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
if (m_VarType == VARTYPE_REG)//Rare and different usage of in/out.
{
helper.Out.x = helper.Out.y = 0;
}
else
{
helper.Out.x = helper.In.x;
helper.Out.y = helper.In.y;
}
helper.Out.z = m_Weight * helper.m_PrecalcSqrtSumSquares;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n";
if (m_VarType == VARTYPE_REG)
{
ss << "\t\tvOut.x = vOut.y = 0;\n";
}
else
{
ss << "\t\tvOut.x = vIn.x;\n"
<< "\t\tvOut.y = vIn.y;\n";
}
ss << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Blur3D.
///
template
class EMBER_API Blur3DVariation : public Variation
{
public:
Blur3DVariation(T weight = 1.0) : Variation("blur3D", VAR_BLUR3D, weight) { }
VARCOPY(Blur3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T angle = rand.Frand01() * M_2PI;
T r = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2);
T angle2 = rand.Frand01() * T(M_PI);
T sina = sin(angle);
T cosa = cos(angle);
T sinb = sin(angle2);
T cosb = cos(angle2);
helper.Out.x = r * sinb * cosa;
helper.Out.y = r * sinb * sina;
helper.Out.z = r * cosb;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\treal_t angle = MwcNext01(mwc) * M_2PI;\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) - 2.0);\n"
<< "\t\treal_t angle2 = MwcNext01(mwc) * M_PI;\n"
<< "\t\treal_t sina = sin(angle);\n"
<< "\t\treal_t cosa = cos(angle);\n"
<< "\t\treal_t sinb = sin(angle2);\n"
<< "\t\treal_t cosb = cos(angle2);\n"
<< "\n"
<< "\t\tvOut.x = r * sinb * cosa;\n"
<< "\t\tvOut.y = r * sinb * sina;\n"
<< "\t\tvOut.z = r * cosb;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Spherical3D.
///
template
class EMBER_API Spherical3DVariation : public Variation
{
public:
Spherical3DVariation(T weight = 1.0) : Variation("Spherical3D", VAR_SPHERICAL3D, weight, true) { }
VARCOPY(Spherical3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r2 = m_Weight / Zeps(helper.m_PrecalcSumSquares + SQR(helper.In.z));
helper.Out.x = r2 * helper.In.x;
helper.Out.y = r2 * helper.In.y;
helper.Out.z = r2 * helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\treal_t r2 = xform->m_VariationWeights[" << varIndex << "] / Zeps(precalcSumSquares + SQR(vIn.z));\n"
<< "\n"
<< "\t\tvOut.x = r2 * vIn.x;\n"
<< "\t\tvOut.y = r2 * vIn.y;\n"
<< "\t\tvOut.z = r2 * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
};
///
/// Curl3D.
///
template
class EMBER_API Curl3DVariation : public ParametricVariation
{
public:
Curl3DVariation(T weight = 1.0) : ParametricVariation("curl3D", VAR_CURL3D, weight, true)
{
Init();
}
PARVARCOPY(Curl3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r2 = helper.m_PrecalcSumSquares + SQR(helper.In.z);
T r = m_Weight / Zeps(r2 * m_C2 + m_C2x * helper.In.x - m_C2y * helper.In.y + m_C2z * helper.In.z + 1);
helper.Out.x = r * (helper.In.x + m_Cx * r2);
helper.Out.y = r * (helper.In.y - m_Cy * r2);
helper.Out.z = r * (helper.In.z + m_Cz * r2);
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string cx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cz = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string c2z = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r2 = precalcSumSquares + SQR(vIn.z);\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / Zeps(r2 * " << c2 << " + " << c2x << " * vIn.x - " << c2y << " * vIn.y + " << c2z << " * vIn.z + 1.0);\n"
<< "\n"
<< "\t\tvOut.x = r * (vIn.x + " << cx << " * r2);\n"
<< "\t\tvOut.y = r * (vIn.y - " << cy << " * r2);\n"
<< "\t\tvOut.z = r * (vIn.z + " << cz << " * r2);\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_C2x = 2 * m_Cx;
m_C2y = 2 * m_Cy;
m_C2z = 2 * m_Cz;
m_C2 = SQR(m_Cx) + SQR(m_Cy) + SQR(m_Cz);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Cx, prefix + "curl3D_cx"));
m_Params.push_back(ParamWithName(&m_Cy, prefix + "curl3D_cy"));
m_Params.push_back(ParamWithName(&m_Cz, prefix + "curl3D_cz"));
m_Params.push_back(ParamWithName(true, &m_C2, prefix + "curl3D_c2"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_C2x, prefix + "curl3D_c2x"));
m_Params.push_back(ParamWithName(true, &m_C2y, prefix + "curl3D_c2y"));
m_Params.push_back(ParamWithName(true, &m_C2z, prefix + "curl3D_c2z"));
}
private:
T m_Cx;
T m_Cy;
T m_Cz;
T m_C2;//Precalc.
T m_C2x;
T m_C2y;
T m_C2z;
};
///
/// Disc3D.
///
template
class EMBER_API Disc3DVariation : public ParametricVariation
{
public:
Disc3DVariation(T weight = 1.0) : ParametricVariation("disc3d", VAR_DISC3D, weight, true, true, false, true, false)
{
Init();
}
PARVARCOPY(Disc3DVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = helper.m_PrecalcSqrtSumSquares;
T temp = r * m_Pi;
T sr = sin(temp);
T cr = cos(temp);
T vv = m_Weight * helper.m_PrecalcAtanxy / Zeps(m_Pi);
helper.Out.x = vv * sr;
helper.Out.y = vv * cr;
helper.Out.z = vv * (r * cos(helper.In.z));
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t r = precalcSqrtSumSquares;\n"
<< "\t\treal_t temp = r * " << pi << ";\n"
<< "\t\treal_t sr = sin(temp);\n"
<< "\t\treal_t cr = cos(temp);\n"
<< "\t\treal_t vv = xform->m_VariationWeights[" << varIndex << "] * precalcAtanxy / Zeps(" << pi << ");\n"
<< "\n"
<< "\t\tvOut.x = vv * sr;\n"
<< "\t\tvOut.y = vv * cr;\n"
<< "\t\tvOut.z = vv * (r * cos(vIn.z));\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Pi, prefix + "disc3d_pi", T(M_PI)));
}
private:
T m_Pi;
};
///
/// Boarders2.
///
template
class EMBER_API Boarders2Variation : public ParametricVariation
{
public:
Boarders2Variation(T weight = 1.0) : ParametricVariation("boarders2", VAR_BOARDERS2, weight)
{
Init();
}
PARVARCOPY(Boarders2Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T roundX = T(int(helper.In.x >= 0 ? int(helper.In.x + T(0.5)) : int(helper.In.x - T(0.5))));
T roundY = T(int(helper.In.y >= 0 ? int(helper.In.y + T(0.5)) : int(helper.In.y - T(0.5))));
T offsetX = helper.In.x - roundX;
T offsetY = helper.In.y - roundY;
if (rand.Frand01() >= m_Cr)
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY);
}
else
{
if (fabs(offsetX) >= fabs(offsetY))
{
if (offsetX >= 0)
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX + m_Cl);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY + m_Cl * offsetY / offsetX);
}
else
{
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX - m_Cl);
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY - m_Cl * offsetY / offsetX);
}
}
else
{
if(offsetY >= 0)
{
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY + m_Cl);
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX + offsetX / offsetY * m_Cl);
}
else
{
helper.Out.y = m_Weight * (offsetY * m_AbsC + roundY - m_Cl);
helper.Out.x = m_Weight * (offsetX * m_AbsC + roundX - offsetX / offsetY * m_Cl);
}
}
}
helper.Out.z = 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 c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string l = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string r = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string absc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cl = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cr = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t roundX = (real_t)(int)(vIn.x >= 0 ? (int)(vIn.x + 0.5) : (int)(vIn.x - 0.5));\n"
<< "\t\treal_t roundY = (real_t)(int)(vIn.y >= 0 ? (int)(vIn.y + 0.5) : (int)(vIn.y - 0.5));\n"
<< "\t\treal_t offsetX = vIn.x - roundX;\n"
<< "\t\treal_t offsetY = vIn.y - roundY;\n"
<< "\n"
<< "\t\tif (MwcNext01(mwc) >= " << cr << ")\n"
<< "\t\t{\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * " << absc << " + roundX);\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * " << absc << " + roundY);\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (fabs(offsetX) >= fabs(offsetY))\n"
<< "\t\t {\n"
<< "\t\t if (offsetX >= 0)\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * " << absc << " + roundX + " << cl << ");\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * " << absc << " + roundY + " << cl << " * offsetY / offsetX);\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * " << absc << " + roundX - " << cl << ");\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * " << absc << " + roundY - " << cl << " * offsetY / offsetX);\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t if(offsetY >= 0)\n"
<< "\t\t {\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * " << absc << " + roundY + " << cl << ");\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * " << absc << " + roundX + offsetX / offsetY * " << cl << ");\n"
<< "\t\t }\n"
<< "\t\t else\n"
<< "\t\t {\n"
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * " << absc << " + roundY - " << cl << ");\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * " << absc << " + roundX - offsetX / offsetY * " << cl << ");\n"
<< "\t\t }\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
T c = Zeps(fabs(m_C));
T cl = Zeps(fabs(m_Left));
T cr = Zeps(fabs(m_Right));
m_AbsC = c;
m_Cl = c * cl;
m_Cr = c + (c * cr);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_C, prefix + "boarders2_c", T(0.5)));
m_Params.push_back(ParamWithName(&m_Left, prefix + "boarders2_left", T(0.5)));
m_Params.push_back(ParamWithName(&m_Right, prefix + "boarders2_right", T(0.5)));
m_Params.push_back(ParamWithName(true, &m_AbsC, prefix + "boarders2_cabs"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cl, prefix + "boarders2_cl"));
m_Params.push_back(ParamWithName(true, &m_Cr, prefix + "boarders2_cr"));
}
private:
T m_C;
T m_Left;
T m_Right;
T m_AbsC;//Precalc.
T m_Cl;
T m_Cr;
};
///
/// Cardioid.
///
template
class EMBER_API CardioidVariation : public ParametricVariation
{
public:
CardioidVariation(T weight = 1.0) : ParametricVariation("cardioid", VAR_CARDIOID, weight, true, true, true, false, true)
{
Init();
}
PARVARCOPY(CardioidVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T r = m_Weight * sqrt(helper.m_PrecalcSumSquares + sin(helper.m_PrecalcAtanyx * m_A) + 1);
helper.Out.x = r * helper.m_PrecalcCosa;
helper.Out.y = r * helper.m_PrecalcSina;
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;
ss << "\t{\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * sqrt(precalcSumSquares + sin(precalcAtanyx * " << a << ") + 1);\n"
<< "\n"
<< "\t\tvOut.x = r * precalcCosa;\n"
<< "\t\tvOut.y = r * precalcSina;\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 + "cardioid_a", 1));
}
private:
T m_A;
};
///
/// Checks.
///
template
class EMBER_API ChecksVariation : public ParametricVariation
{
public:
ChecksVariation(T weight = 1.0) : ParametricVariation("checks", VAR_CHECKS, weight)
{
Init();
}
PARVARCOPY(ChecksVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T dx, dy;
T rnx = m_Rnd * rand.Frand01();
T rny = m_Rnd * rand.Frand01();
int isXY = int(LRint(helper.In.x * m_Cs) + LRint(helper.In.y * m_Cs));
if (isXY % 2)
{
dx = m_Ncx + rnx;
dy = m_Ncy;
}
else
{
dx = m_Cx;
dy = m_Cy + rny;
}
helper.Out.x = m_Weight * (helper.In.x + dx);
helper.Out.y = m_Weight * (helper.In.y + dy);
helper.Out.z = m_Weight * helper.In.z;
}
virtual string OpenCLString() 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 size = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rnd = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cs = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ncx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ncy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t dx, dy;\n"
<< "\t\treal_t rnx = " << rnd << " * MwcNext01(mwc);\n"
<< "\t\treal_t rny = " << rnd << " * MwcNext01(mwc);\n"
<< "\n"
<< "\t\tint isXY = (int)(LRint(vIn.x * " << cs << ") + LRint(vIn.y * " << cs << "));\n"
<< "\n"
<< "\t\tif (isXY % 2)\n"
<< "\t\t{\n"
<< "\t\t dx = " << ncx << " + rnx;\n"
<< "\t\t dy = " << ncy << ";\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t dx = " << cx << ";\n"
<< "\t\t dy = " << cy << " + rny;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + dx);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + dy);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Cs = 1 / Zeps(m_Size);
m_Cx = m_X;
m_Cy = m_Y;
m_Ncx = -m_X;
m_Ncy = -m_Y;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_X, prefix + "checks_x", T(0.5)));
m_Params.push_back(ParamWithName(&m_Y, prefix + "checks_y", T(0.5)));
m_Params.push_back(ParamWithName(&m_Size, prefix + "checks_size", T(0.5)));
m_Params.push_back(ParamWithName(&m_Rnd, prefix + "checks_rnd"));
m_Params.push_back(ParamWithName(true, &m_Cs, prefix + "checks_cs"));//Precalc.
m_Params.push_back(ParamWithName(true, &m_Cx, prefix + "checks_cx"));
m_Params.push_back(ParamWithName(true, &m_Cy, prefix + "checks_cy"));
m_Params.push_back(ParamWithName(true, &m_Ncx, prefix + "checks_ncx"));
m_Params.push_back(ParamWithName(true, &m_Ncy, prefix + "checks_ncy"));
}
private:
T m_X;
T m_Y;
T m_Size;
T m_Rnd;
T m_Cs;//Precalc.
T m_Cx;
T m_Cy;
T m_Ncx;
T m_Ncy;
};
///
/// Circlize.
///
template
class EMBER_API CirclizeVariation : public ParametricVariation
{
public:
CirclizeVariation(T weight = 1.0) : ParametricVariation("circlize", VAR_CIRCLIZE, weight)
{
Init();
}
PARVARCOPY(CirclizeVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T side;
T perimeter;
T r, val;
T absx = fabs(helper.In.x);
T absy = fabs(helper.In.y);
if (absx >= absy)
{
if (helper.In.x >= absy)
perimeter = absx + helper.In.y;
else
perimeter = 5 * absx - helper.In.y;
side = absx;
}
else
{
if (helper.In.y >= absx)
perimeter = 3 * absy - helper.In.x;
else
perimeter = 7 * absy + helper.In.x;
side = absy;
}
r = m_Vvar4Pi * side + m_Hole;
val = T(M_PI_4) * perimeter / side - T(M_PI_4);
helper.Out.x = r * cos(val);
helper.Out.y = r * sin(val);
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 hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string vvar4pi = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t side;\n"
<< "\t\treal_t perimeter;\n"
<< "\t\treal_t absx = fabs(vIn.x);\n"
<< "\t\treal_t absy = fabs(vIn.y);\n"
<< "\n"
<< "\t\tif (absx >= absy)\n"
<< "\t\t{\n"
<< "\t\t if (vIn.x >= absy)\n"
<< "\t\t perimeter = absx + vIn.y;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 5 * absx - vIn.y;\n"
<< "\n"
<< "\t\t side = absx;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (vIn.y >= absx)\n"
<< "\t\t perimeter = 3 * absy - vIn.x;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 7 * absy + vIn.x;\n"
<< "\n"
<< "\t\t side = absy;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r = " << vvar4pi << " * side + " << hole << ";\n"
<< "\t\treal_t val = M_PI_4 * perimeter / side - M_PI_4;\n"
<< "\n"
<< "\t\tvOut.x = r * cos(val);\n"
<< "\t\tvOut.y = r * sin(val);\n"
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Vvar4Pi = m_Weight / T(M_PI_4);
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Hole, prefix + "circlize_hole"));
m_Params.push_back(ParamWithName(true, &m_Vvar4Pi, prefix + "circlize_vvar4pi"));//Precalc.
}
private:
T m_Hole;
T m_Vvar4Pi;//Precalc.
};
///
/// Circlize2.
///
template
class EMBER_API Circlize2Variation : public ParametricVariation
{
public:
Circlize2Variation(T weight = 1.0) : ParametricVariation("circlize2", VAR_CIRCLIZE2, weight)
{
Init();
}
PARVARCOPY(Circlize2Variation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T side;
T perimeter;
T absx = fabs(helper.In.x);
T absy = fabs(helper.In.y);
if (absx >= absy)
{
if (helper.In.x >= absy)
perimeter = absx + helper.In.y;
else
perimeter = 5 * absx - helper.In.y;
side = absx;
}
else
{
if (helper.In.y >= absx)
perimeter = 3 * absy - helper.In.x;
else
perimeter = 7 * absy + helper.In.x;
side = absy;
}
T r = m_Weight * (side + m_Hole);
T val = T(M_PI_4) * perimeter / side - T(M_PI_4);
helper.Out.x = r * cos(val);
helper.Out.y = r * sin(val);
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 hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t side;\n"
<< "\t\treal_t perimeter;\n"
<< "\t\treal_t absx = fabs(vIn.x);\n"
<< "\t\treal_t absy = fabs(vIn.y);\n"
<< "\n"
<< "\t\tif (absx >= absy)\n"
<< "\t\t{\n"
<< "\t\t if (vIn.x >= absy)\n"
<< "\t\t perimeter = absx + vIn.y;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 5 * absx - vIn.y;\n"
<< "\n"
<< "\t\t side = absx;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t if (vIn.y >= absx)\n"
<< "\t\t perimeter = 3 * absy - vIn.x;\n"
<< "\t\t else\n"
<< "\t\t perimeter = 7 * absy + vIn.x;\n"
<< "\n"
<< "\t\t side = absy;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * (side + " << hole << ");\n"
<< "\t\treal_t val = M_PI_4 * perimeter / side - M_PI_4;\n"
<< "\n"
<< "\t\tvOut.x = r * cos(val);\n"
<< "\t\tvOut.y = r * sin(val);\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_Hole, prefix + "circlize2_hole"));
}
private:
T m_Hole;
};
///
/// CosWrap.
///
template
class EMBER_API CosWrapVariation : public ParametricVariation
{
public:
CosWrapVariation(T weight = 1.0) : ParametricVariation("coswrap", VAR_COS_WRAP, weight)
{
Init();
}
PARVARCOPY(CosWrapVariation)
virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override
{
T x = T(0.5) * helper.In.x + T(0.5);
T y = T(0.5) * helper.In.y + T(0.5);
T bx = Fabsmod(m_Fr * x);
T by = Fabsmod(m_Fr * y);
T oscnapx = Foscn(m_AmountX, m_Px);
T oscnapy = Foscn(m_AmountY, m_Py);
helper.Out.x = -1 + m_Vv2 * Lerp(Lerp(x, Fosc(x, T(4), m_Px), oscnapx), Fosc(bx, T(4), m_Px), oscnapx);//Original did a direct assignment to outPoint, which is incompatible with Ember's design.
helper.Out.y = -1 + m_Vv2 * Lerp(Lerp(y, Fosc(y, T(4), m_Py), oscnapy), Fosc(by, T(4), m_Py), oscnapy);
helper.Out.z = (m_VarType == VARTYPE_REG) ? 0 : helper.In.z;
}
virtual string OpenCLString() override
{
ostringstream ss, ss2;
int i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string repeat = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string amountX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string amountY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phaseX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string phaseY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ax = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string ay = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string px = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string py = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string fr = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string vv2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x = 0.5 * vIn.x + 0.5;\n"
<< "\t\treal_t y = 0.5 * vIn.y + 0.5;\n"
<< "\t\treal_t bx = Fabsmod(" << fr << " * x);\n"
<< "\t\treal_t by = Fabsmod(" << fr << " * y);\n"
<< "\t\treal_t oscnapx = Foscn(" << amountX << ", " << px << ");\n"
<< "\t\treal_t oscnapy = Foscn(" << amountY << ", " << py << ");\n"
<< "\n"
<< "\t\tvOut.x = -1 + " << vv2 << " * Lerp(Lerp(x, Fosc(x, 4, " << px << "), oscnapx), Fosc(bx, 4, " << px << "), oscnapx);\n"
<< "\t\tvOut.y = -1 + " << vv2 << " * Lerp(Lerp(y, Fosc(y, 4, " << py << "), oscnapy), Fosc(by, 4, " << py << "), oscnapy);\n"
<< "\t\tvOut.z = " << ((m_VarType == VARTYPE_REG) ? "0" : "vIn.z") << ";\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_Ax = M_2PI * fabs(m_AmountX);
m_Ay = M_2PI * fabs(m_AmountY);
m_Px = T(M_PI) * m_PhaseX;
m_Py = T(M_PI) * m_PhaseY;
m_Fr = fabs(m_Repeat);
m_Vv2 = 2 * m_Weight;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName(&m_Repeat, prefix + "coswrap_repeat", 1, INTEGER_NONZERO));
m_Params.push_back(ParamWithName(&m_AmountX, prefix + "coswrap_amount_x"));
m_Params.push_back(ParamWithName