mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-22 05:30:06 -05:00
59f5bffc3c
--Added panorama1 and panorama2 variations. Bug fixes: --crackle had a bug with Nvidia GPUs. Code changes: --crackle now uses real_t* for cache rather than real2. This is what was causing the bug. --Make the local offsets array used in crackle a precalc since it's the same for all. This reduces register pressure. --Get rid of all usages of real3, just to be safe since Nvidia doesn't like them. --#define TOTAL_GLOBAL_SIZE_END in the OpenCL iteration kernel just for debugging purposes to see how large the parvars buffer is.
1567 lines
53 KiB
C++
1567 lines
53 KiB
C++
#pragma once
|
|
|
|
#include "Variation.h"
|
|
|
|
namespace EmberNs
|
|
{
|
|
/// <summary>
|
|
/// splits3D.
|
|
/// </summary>
|
|
template <typename T>
|
|
class Splits3DVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
Splits3DVariation(T weight = 1.0) : ParametricVariation<T>("splits3D", eVariationId::VAR_SPLITS3D, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(Splits3DVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
if (helper.In.x >= 0)
|
|
helper.Out.x = m_Weight * (helper.In.x + m_X);
|
|
else
|
|
helper.Out.x = m_Weight * (helper.In.x - m_X);
|
|
|
|
if (helper.In.y >= 0)
|
|
helper.Out.y = m_Weight * (helper.In.y + m_Y);
|
|
else
|
|
helper.Out.y = m_Weight * (helper.In.y - m_Y);
|
|
|
|
if (helper.In.z >= 0)
|
|
helper.Out.z = m_Weight * (helper.In.z + m_Z);
|
|
else
|
|
helper.Out.z = m_Weight * (helper.In.z - m_Z);
|
|
}
|
|
|
|
virtual string OpenCLString() const 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\tif (vIn.x >= 0)\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + " << x << ");\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x - " << x << ");\n"
|
|
<< "\n"
|
|
<< "\t\tif (vIn.y >= 0)\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + " << y << ");\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y - " << y << ");\n"
|
|
<< "\n"
|
|
<< "\t\tif (vIn.z >= 0)\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * (vIn.z + " << z << ");\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * (vIn.z - " << z << ");\n"
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual void Random(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
m_X = rand.Frand11<T>();
|
|
m_Y = rand.Frand11<T>();
|
|
m_Z = rand.Frand11<T>();
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "splits3D_x"));
|
|
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "splits3D_y"));
|
|
m_Params.push_back(ParamWithName<T>(&m_Z, prefix + "splits3D_z"));
|
|
}
|
|
|
|
private:
|
|
T m_X;
|
|
T m_Y;
|
|
T m_Z;
|
|
};
|
|
|
|
/// <summary>
|
|
/// waves2b.
|
|
/// Note that _j1() is not implemented in OpenCL, so that conditional is skipped
|
|
/// when running on the GPU. The results might look different.
|
|
/// </summary>
|
|
template <typename T>
|
|
class Waves2BVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
Waves2BVariation(T weight = 1.0) : ParametricVariation<T>("waves2b", eVariationId::VAR_WAVES2B, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(Waves2BVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T CsX = 1;
|
|
T CsY = 1;
|
|
T jcbSn = 0, jcbCn, jcbDn;
|
|
CsX = VarFuncs<T>::SafeDivInv(m_Unity, (m_Unity + Sqr(helper.In.x)));
|
|
CsX = CsX * m_Six + m_Scaleinfx;
|
|
CsY = VarFuncs<T>::SafeDivInv(m_Unity, (m_Unity + Sqr(helper.In.y)));
|
|
CsY = CsY * m_Siy + m_Scaleinfy;
|
|
|
|
if (m_Pwx >= 0 && m_Pwx < 1e-4)
|
|
{
|
|
VarFuncs<T>::JacobiElliptic(helper.In.y * m_Freqx, m_Jacok, jcbSn, jcbCn, jcbDn);
|
|
helper.Out.x = m_Weight * (helper.In.x + CsX * jcbSn);
|
|
}
|
|
else if (m_Pwx < 0 && m_Pwx > -1e-4)
|
|
#ifdef _WIN32
|
|
helper.Out.x = m_Weight * (helper.In.x + CsX * T(_j1(helper.In.y * m_Freqx)));//This is not implemented in OpenCL.
|
|
|
|
#else
|
|
helper.Out.x = m_Weight * (helper.In.x + CsX * T(j1(helper.In.y * m_Freqx)));//This is not implemented in OpenCL.
|
|
#endif
|
|
else
|
|
helper.Out.x = m_Weight * (helper.In.x + CsX * std::sin(VarFuncs<T>::SignNz(helper.In.y) * std::pow(Zeps(std::abs(helper.In.y)), m_Pwx) * m_Freqx));
|
|
|
|
if (m_Pwy >= 0 && m_Pwy < 1e-4)
|
|
{
|
|
VarFuncs<T>::JacobiElliptic(helper.In.x * m_Freqy, m_Jacok, jcbSn, jcbCn, jcbDn);
|
|
helper.Out.y = m_Weight * (helper.In.y + CsY * jcbSn);
|
|
}
|
|
else if (m_Pwy < 0 && m_Pwy > -1e-4)
|
|
#ifdef _WIN32
|
|
helper.Out.y = m_Weight * (helper.In.y + CsY * T(_j1(helper.In.x * m_Freqy)));
|
|
|
|
#else
|
|
helper.Out.y = m_Weight * (helper.In.y + CsY * T(j1(helper.In.x * m_Freqy)));
|
|
#endif
|
|
else
|
|
helper.Out.y = m_Weight * (helper.In.y + CsY * std::sin(VarFuncs<T>::SignNz(helper.In.x) * std::pow(Zeps(std::abs(helper.In.x)), m_Pwy) * m_Freqy));
|
|
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string freqx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string freqy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string pwx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string pwy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scalex = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scaleinfx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scaley = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scaleinfy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string unity = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string jacok = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string six = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
|
string siy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t CsX = 1;\n"
|
|
<< "\t\treal_t CsY = 1;\n"
|
|
<< "\t\treal_t jcbSn = 0, jcbCn, jcbDn;\n"
|
|
<< "\t\tCsX = SafeDivInv(" << unity << ", (" << unity << " + Sqr(vIn.x)));\n"
|
|
<< "\t\tCsX = CsX * " << six << " + " << scaleinfx << ";\n"
|
|
<< "\t\tCsY = SafeDivInv(" << unity << ", (" << unity << " + Sqr(vIn.y)));\n"
|
|
<< "\t\tCsY = CsY * " << siy << " + " << scaleinfy << ";\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << pwx << " >= 0 && " << pwx << " < 1e-4)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t JacobiElliptic(vIn.y * " << freqx << ", " << jacok << ", &jcbSn, &jcbCn, &jcbDn);\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + CsX * jcbSn);\n"
|
|
<< "\t\t}\n"
|
|
//<< "\t\telse if (" << pwx << " < 0 && " << pwx << " > -1e-4)\n"
|
|
//<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + CsX * _j1(vIn.y * " << freqx << "));\n"//This is not implemented in OpenCL.
|
|
<< "\t\telse\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + CsX * sin(SignNz(vIn.y) * pow(Zeps(fabs(vIn.y)), " << pwx << ") * " << freqx << "));\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << pwy << " >= 0 && " << pwy << " < 1e-4)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t JacobiElliptic(vIn.x * " << freqy << ", " << jacok << ", &jcbSn, &jcbCn, &jcbDn);\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + CsY * jcbSn);\n"
|
|
<< "\t\t}\n"
|
|
//<< "\t\telse if (" << pwy << " < 0 && " << pwy << " > -1e-4)\n"
|
|
//<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + CsY * _j1(vIn.x * " << freqy << "));\n"//This is not implemented in OpenCL.
|
|
<< "\t\telse\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + CsY * sin(SignNz(vIn.x) * pow(Zeps(fabs(vIn.x)), " << pwy << ") * " << freqy << "));\n"
|
|
<< "\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps", "Sqr", "SignNz", "SafeDivInv", "JacobiElliptic" };
|
|
}
|
|
|
|
virtual void Precalc() override
|
|
{
|
|
m_Six = m_Scalex - m_Scaleinfx;
|
|
m_Siy = m_Scaley - m_Scaleinfy;
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Freqx, prefix + "waves2b_freqx", 2));
|
|
m_Params.push_back(ParamWithName<T>(&m_Freqy, prefix + "waves2b_freqy", 2));
|
|
m_Params.push_back(ParamWithName<T>(&m_Pwx, prefix + "waves2b_pwx", 1, eParamType::REAL, -10, 10));
|
|
m_Params.push_back(ParamWithName<T>(&m_Pwy, prefix + "waves2b_pwy", 1, eParamType::REAL, -10, 10));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scalex, prefix + "waves2b_scalex", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scaleinfx, prefix + "waves2b_scaleinfx", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scaley, prefix + "waves2b_scaley", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scaleinfy, prefix + "waves2b_scaleinfy", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Unity, prefix + "waves2b_unity", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Jacok, prefix + "waves2b_jacok", T(0.25), eParamType::REAL, -1, 1));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Six, prefix + "waves2b_six"));//Precalc.
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Siy, prefix + "waves2b_siy"));
|
|
}
|
|
|
|
private:
|
|
T m_Freqx;
|
|
T m_Freqy;
|
|
T m_Pwx;
|
|
T m_Pwy;
|
|
T m_Scalex;
|
|
T m_Scaleinfx;
|
|
T m_Scaley;
|
|
T m_Scaleinfy;
|
|
T m_Unity;
|
|
T m_Jacok;
|
|
T m_Six;//Precalc.
|
|
T m_Siy;
|
|
};
|
|
|
|
/// <summary>
|
|
/// jac_cn.
|
|
/// </summary>
|
|
template <typename T>
|
|
class JacCnVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
JacCnVariation(T weight = 1.0) : ParametricVariation<T>("jac_cn", eVariationId::VAR_JAC_CN, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(JacCnVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T snx, cnx, dnx;
|
|
T sny, cny, dny;
|
|
T numX, numY, denom;
|
|
VarFuncs<T>::JacobiElliptic(helper.In.x, m_K, snx, cnx, dnx);
|
|
VarFuncs<T>::JacobiElliptic(helper.In.y, 1 - m_K, sny, cny, dny);
|
|
numX = cnx * cny;
|
|
numY = -dnx * snx * dny * sny;
|
|
denom = SQR(snx) * SQR(sny) * m_K + SQR(cny);
|
|
denom = m_Weight / Zeps(denom);
|
|
helper.Out.x = denom * numX;
|
|
helper.Out.y = denom * numY;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string k = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t snx, cnx, dnx;\n"
|
|
<< "\t\treal_t sny, cny, dny;\n"
|
|
<< "\t\treal_t numX, numY, denom;\n"
|
|
<< "\t\tJacobiElliptic(vIn.x, " << k << ", &snx, &cnx, &dnx);\n"
|
|
<< "\t\tJacobiElliptic(vIn.y, 1 - " << k << ", &sny, &cny, &dny);\n"
|
|
<< "\t\tnumX = cnx * cny;\n"
|
|
<< "\t\tnumY = -dnx * snx * dny * sny;\n"
|
|
<< "\t\tdenom = SQR(snx) * SQR(sny) * " << k << " + SQR(cny);\n"
|
|
<< "\t\tdenom = xform->m_VariationWeights[" << varIndex << "] / Zeps(denom);\n"
|
|
<< "\t\tvOut.x = denom * numX;\n"
|
|
<< "\t\tvOut.y = denom * numY;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps", "JacobiElliptic" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_K, prefix + "jac_cn_k", T(0.5), eParamType::REAL, -1, 1));
|
|
}
|
|
|
|
private:
|
|
T m_K;
|
|
};
|
|
|
|
/// <summary>
|
|
/// jac_dn.
|
|
/// </summary>
|
|
template <typename T>
|
|
class JacDnVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
JacDnVariation(T weight = 1.0) : ParametricVariation<T>("jac_dn", eVariationId::VAR_JAC_DN, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(JacDnVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T snx, cnx, dnx;
|
|
T sny, cny, dny;
|
|
T numX, numY, denom;
|
|
VarFuncs<T>::JacobiElliptic(helper.In.x, m_K, snx, cnx, dnx);
|
|
VarFuncs<T>::JacobiElliptic(helper.In.y, 1 - m_K, sny, cny, dny);
|
|
numX = dnx * cny * dny;
|
|
numY = -cnx * snx * sny * m_K;
|
|
denom = SQR(snx) * SQR(sny) * m_K + SQR(cny);
|
|
denom = m_Weight / Zeps(denom);
|
|
helper.Out.x = denom * numX;
|
|
helper.Out.y = denom * numY;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string k = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t snx, cnx, dnx;\n"
|
|
<< "\t\treal_t sny, cny, dny;\n"
|
|
<< "\t\treal_t numX, numY, denom;\n"
|
|
<< "\t\tJacobiElliptic(vIn.x, " << k << ", &snx, &cnx, &dnx);\n"
|
|
<< "\t\tJacobiElliptic(vIn.y, 1 - " << k << ", &sny, &cny, &dny);\n"
|
|
<< "\t\tnumX = dnx * cny * dny;\n"
|
|
<< "\t\tnumY = -cnx * snx * sny * " << k << ";\n"
|
|
<< "\t\tdenom = SQR(snx) * SQR(sny) * " << k << " + SQR(cny);\n"
|
|
<< "\t\tdenom = xform->m_VariationWeights[" << varIndex << "] / Zeps(denom);\n"
|
|
<< "\t\tvOut.x = denom * numX;\n"
|
|
<< "\t\tvOut.y = denom * numY;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps", "JacobiElliptic" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_K, prefix + "jac_dn_k", T(0.5), eParamType::REAL, -1, 1));
|
|
}
|
|
|
|
private:
|
|
T m_K;
|
|
};
|
|
|
|
/// <summary>
|
|
/// jac_sn.
|
|
/// </summary>
|
|
template <typename T>
|
|
class JacSnVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
JacSnVariation(T weight = 1.0) : ParametricVariation<T>("jac_sn", eVariationId::VAR_JAC_SN, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(JacSnVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T snx, cnx, dnx;
|
|
T sny, cny, dny;
|
|
T numX, numY, denom;
|
|
VarFuncs<T>::JacobiElliptic(helper.In.x, m_K, snx, cnx, dnx);
|
|
VarFuncs<T>::JacobiElliptic(helper.In.y, 1 - m_K, sny, cny, dny);
|
|
numX = snx * dny;
|
|
numY = cnx * dnx * cny * sny;
|
|
denom = SQR(snx) * SQR(sny) * m_K + SQR(cny);
|
|
denom = m_Weight / Zeps(denom);
|
|
helper.Out.x = denom * numX;
|
|
helper.Out.y = denom * numY;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string k = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t snx, cnx, dnx;\n"
|
|
<< "\t\treal_t sny, cny, dny;\n"
|
|
<< "\t\treal_t numX, numY, denom;\n"
|
|
<< "\t\tJacobiElliptic(vIn.x, " << k << ", &snx, &cnx, &dnx);\n"
|
|
<< "\t\tJacobiElliptic(vIn.y, 1 - " << k << ", &sny, &cny, &dny);\n"
|
|
<< "\t\tnumX = snx * dny;\n"
|
|
<< "\t\tnumY = cnx * dnx * cny * sny;\n"
|
|
<< "\t\tdenom = SQR(snx) * SQR(sny) * " << k << " + SQR(cny);\n"
|
|
<< "\t\tdenom = xform->m_VariationWeights[" << varIndex << "] / Zeps(denom);\n"
|
|
<< "\t\tvOut.x = denom * numX;\n"
|
|
<< "\t\tvOut.y = denom * numY;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps", "JacobiElliptic" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_K, prefix + "jac_sn_k", T(0.5), eParamType::REAL, -1, 1));
|
|
}
|
|
|
|
private:
|
|
T m_K;
|
|
};
|
|
|
|
/// <summary>
|
|
/// pressure_wave.
|
|
/// </summary>
|
|
template <typename T>
|
|
class PressureWaveVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
PressureWaveVariation(T weight = 1.0) : ParametricVariation<T>("pressure_wave", eVariationId::VAR_PRESSURE_WAVE, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(PressureWaveVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
helper.Out.x = m_Weight * (helper.In.x + (1 / Zeps(m_X * M_2PI)) * std::sin(m_X * M_2PI * helper.In.x));
|
|
helper.Out.y = m_Weight * (helper.In.y + (1 / Zeps(m_Y * M_2PI)) * std::sin(m_Y * M_2PI * helper.In.y));
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + (1 / Zeps(" << x << " * M_2PI)) * sin(" << x << " * M_2PI * vIn.x));\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + (1 / Zeps(" << y << " * M_2PI)) * sin(" << y << " * M_2PI * vIn.y));\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "pressure_wave_x_freq", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "pressure_wave_y_freq", 1));
|
|
}
|
|
|
|
private:
|
|
T m_X;
|
|
T m_Y;
|
|
};
|
|
|
|
/// <summary>
|
|
/// gamma.
|
|
/// </summary>
|
|
template <typename T>
|
|
class GammaVariation : public Variation<T>
|
|
{
|
|
public:
|
|
GammaVariation(T weight = 1.0) : Variation<T>("gamma", eVariationId::VAR_GAMMA, weight, true, true, false, false, true)
|
|
{
|
|
}
|
|
|
|
VARCOPY(GammaVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
helper.Out.x = m_Weight * std::lgamma(helper.m_PrecalcSqrtSumSquares);
|
|
helper.Out.y = m_Weight * helper.m_PrecalcAtanyx;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
ss << "\t{\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * lgamma(precalcSqrtSumSquares);\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcAtanyx;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
/// <summary>
|
|
/// prose3D.
|
|
/// </summary>
|
|
template <typename T>
|
|
class PRose3DVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
PRose3DVariation(T weight = 1.0) : ParametricVariation<T>("pRose3D", eVariationId::VAR_PROSE3D, weight, true, true, false, false, true)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(PRose3DVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
int posNeg = 1;
|
|
T th = 0;
|
|
T sth, cth, pang, wig, wag, wag2, wag3, wag12 = 0, waggle = 0;
|
|
T rad = helper.m_PrecalcSqrtSumSquares;
|
|
T curve1 = rad / m_L;
|
|
T curve2 = Sqr(curve1);
|
|
T curve3 = (rad - m_L * T(0.5)) / m_L;
|
|
T curve4 = Sqr(curve2);
|
|
th = helper.m_PrecalcAtanyx;
|
|
sincos(th, &sth, &cth);
|
|
|
|
if (rand.Frand01<T>() < T(0.5))
|
|
posNeg = -1;
|
|
|
|
pang = th / Zeps(m_Cycle);
|
|
wig = pang * m_Freq * T(0.5) + m_Offset * m_Cycle;
|
|
|
|
if (m_OptDir < 0)
|
|
{
|
|
wag = std::sin(curve1 * T(M_PI) * m_AbsOptSc) + m_Wagsc * T(0.4) * rad + m_Crvsc * T(0.5) * (std::sin(curve2 * T(M_PI)));
|
|
wag3 = std::sin(curve4 * T(M_PI) * m_AbsOptSc) + m_Wagsc * SQR(rad) * T(0.4) + m_Crvsc * T(0.5) * (std::cos(curve3 * T(M_PI)));
|
|
}
|
|
else
|
|
{
|
|
wag = std::sin(curve1 * T(M_PI) * m_AbsOptSc) + m_Wagsc * T(0.4) * rad + m_Crvsc * T(0.5) * (std::cos(curve3 * T(M_PI)));
|
|
wag3 = std::sin(curve4 * T(M_PI) * m_AbsOptSc) + m_Wagsc * SQR(rad) * T(0.4) + m_Crvsc * T(0.5) * (std::sin(curve2 * T(M_PI)));
|
|
}
|
|
|
|
wag2 = std::sin(curve2 * T(M_PI) * m_AbsOptSc) + m_Wagsc * T(0.4) * rad + m_Crvsc * T(0.5) * (std::cos(curve3 * T(M_PI)));
|
|
|
|
if (m_Smooth12 <= 1)
|
|
wag12 = wag;
|
|
else if (m_Smooth12 <= 2 && m_Smooth12 > 1)
|
|
wag12 = wag2 * (1 - m_AntiOpt1) + wag * m_AntiOpt1;
|
|
else if (m_Smooth12 > 2)
|
|
wag12 = wag2;
|
|
|
|
if (m_Smooth3 == 0)
|
|
waggle = wag12;
|
|
else if (m_Smooth3 > 0)
|
|
waggle = wag12 * (1 - m_Smooth3) + wag3 * m_Smooth3;
|
|
|
|
if (rand.Frand01<T>() < m_Ghost)
|
|
{
|
|
if (posNeg < 0)
|
|
{
|
|
helper.Out.x = m_Weight * T(0.5) * m_RefSc * (m_L * std::cos(m_NumPetals * th + m_C)) * cth;
|
|
helper.Out.y = m_Weight * T(0.5) * m_RefSc * (m_L * std::cos(m_NumPetals * th + m_C)) * sth;
|
|
helper.Out.z = m_Weight * T(-0.5) * ((m_Z2 * waggle + Sqr(rad * T(0.5)) * std::sin(wig) * m_WigScale) + m_Dist);
|
|
}
|
|
else
|
|
{
|
|
helper.Out.x = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * cth;
|
|
helper.Out.y = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * sth;
|
|
helper.Out.z = m_Weight * T(0.5) * ((m_Z1 * waggle + Sqr(rad * T(0.5)) * std::sin(wig) * m_WigScale) + m_Dist);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (posNeg < 0)
|
|
{
|
|
helper.Out.x = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * cth;
|
|
helper.Out.y = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * sth;
|
|
helper.Out.z = m_Weight * T(0.5) * ((m_Z1 * waggle + Sqr(rad * T(0.5)) * std::sin(wig) * m_WigScale) + m_Dist);
|
|
}
|
|
else
|
|
{
|
|
helper.Out.x = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * cth;
|
|
helper.Out.y = m_Weight * T(0.5) * (m_L * std::cos(m_NumPetals * th + m_C)) * sth;
|
|
helper.Out.z = m_Weight * T(0.5) * ((m_Z1 * waggle + Sqr(rad * T(0.5)) * std::sin(wig) * m_WigScale) + m_Dist);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string l = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string k = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string z1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string z2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string refSc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string opt = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string optSc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string opt3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string transp = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string wagsc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string crvsc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string f = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string wigsc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string cycle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
|
string optDir = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string petalsSign = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string numPetals = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string absOptSc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string smooth12 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string smooth3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string antiOpt1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string ghost = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string freq = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string wigScale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\tint posNeg = 1;\n"
|
|
<< "\t\treal_t th = 0;\n"
|
|
<< "\t\treal_t sth, cth, pang, wig, wag, wag2, wag3, wag12, waggle;\n"
|
|
<< "\t\treal_t rad = precalcSqrtSumSquares;\n"
|
|
<< "\t\treal_t curve1 = rad / " << l << ";\n"
|
|
<< "\t\treal_t curveTwo = Sqr(curve1);\n"
|
|
<< "\t\treal_t curve3 = (rad - " << l << " * 0.5) / " << l << ";\n"
|
|
<< "\t\treal_t curve4 = Sqr(curveTwo);\n"
|
|
<< "\t\tth = precalcAtanyx;\n"
|
|
<< "\t\tsth = sincos(th, &cth);\n"
|
|
<< "\n"
|
|
<< "\t\tif (MwcNext01(mwc) < 0.5)\n"
|
|
<< "\t\t posNeg = -1;\n"
|
|
<< "\n"
|
|
<< "\t\tpang = th / Zeps(" << cycle << ");\n"
|
|
<< "\t\twig = pang * " << freq << " * 0.5 + " << offset << " * " << cycle << ";\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << optDir << " < 0)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t wag = sin(curve1 * MPI * " << absOptSc << ") + " << wagsc << " * 0.4 * rad + " << crvsc << " * 0.5 * (sin(curveTwo * MPI));\n"
|
|
<< "\t\t wag3 = sin(curve4 * MPI * " << absOptSc << ") + " << wagsc << " * SQR(rad) * 0.4 + " << crvsc << " * 0.5 * (cos(curve3 * MPI));\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t wag = sin(curve1 * MPI * " << absOptSc << ") + " << wagsc << " * 0.4 * rad + " << crvsc << " * 0.5 * (cos(curve3 * MPI));\n"
|
|
<< "\t\t wag3 = sin(curve4 * MPI * " << absOptSc << ") + " << wagsc << " * SQR(rad) * 0.4 + " << crvsc << " * 0.5 * (sin(curveTwo * MPI));\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\twag2 = sin(curveTwo * MPI * " << absOptSc << ") + " << wagsc << " * 0.4 * rad + " << crvsc << " * 0.5 * (cos(curve3 * MPI));\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << smooth12 << " <= 1)\n"
|
|
<< "\t\t wag12 = wag;\n"
|
|
<< "\t\telse if (" << smooth12 << " <= 2 && " << smooth12 << " > 1)\n"
|
|
<< "\t\t wag12 = wag2 * (1 - " << antiOpt1 << ") + wag * " << antiOpt1 << ";\n"
|
|
<< "\t\telse if (" << smooth12 << " > 2)\n"
|
|
<< "\t\t wag12 = wag2;\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << smooth3 << " == 0)\n"
|
|
<< "\t\t waggle = wag12;\n"
|
|
<< "\t\telse if (" << smooth3 << " > 0)\n"
|
|
<< "\t\t waggle = wag12 * (1 - " << smooth3 << ") + wag3 * " << smooth3 << ";\n"
|
|
<< "\n"
|
|
<< "\t\tif (MwcNext01(mwc) < " << ghost << ")\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t if (posNeg < 0)\n"
|
|
<< "\t\t {\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * 0.5 * " << refSc << " * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * cth;\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * 0.5 * " << refSc << " * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * sth;\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * -0.5 * ((" << z2 << " * waggle + Sqr(rad * 0.5) * sin(wig) * " << wigScale << ") + " << dist << ");\n"
|
|
<< "\t\t }\n"
|
|
<< "\t\t else\n"
|
|
<< "\t\t {\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * cth;\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * sth;\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * 0.5 * ((" << z1 << " * waggle + Sqr(rad * 0.5) * sin(wig) * " << wigScale << ") + " << dist << ");\n"
|
|
<< "\t\t }\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t if (posNeg < 0)\n"
|
|
<< "\t\t {\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * cth;\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * sth;\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * 0.5 * ((" << z1 << " * waggle + Sqr(rad * 0.5) * sin(wig) * " << wigScale << ") + " << dist << ");\n"
|
|
<< "\t\t }\n"
|
|
<< "\t\t else\n"
|
|
<< "\t\t {\n"
|
|
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * cth;\n"
|
|
<< "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * 0.5 * (" << l << " * cos(" << numPetals << " * th + " << c << ")) * sth;\n"
|
|
<< "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * 0.5 * ((" << z1 << " * waggle + Sqr(rad * 0.5) * sin(wig) * " << wigScale << ") + " << dist << ");\n"
|
|
<< "\t\t }\n"
|
|
<< "\t\t}\n"
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Sqr", "Zeps" };
|
|
}
|
|
|
|
virtual void Precalc() override
|
|
{
|
|
m_Cycle = M_2PI / Zeps(m_K);
|
|
m_NumPetals = m_K;
|
|
m_Ghost = Sqr(m_Transp);
|
|
m_Freq = m_F * M_2PI;
|
|
m_WigScale = m_Wigsc * T(0.5);
|
|
|
|
if (std::abs(m_NumPetals) < T(0.0001))
|
|
m_NumPetals = T(0.0001) * m_PetalsSign;
|
|
|
|
m_Smooth12 = std::abs(m_Opt);
|
|
m_Smooth3 = std::abs(m_Opt3);
|
|
m_AbsOptSc = std::abs(m_OptSc);
|
|
|
|
if (m_Smooth12 > 2)
|
|
m_Smooth12 = 2;
|
|
|
|
m_AntiOpt1 = 2 - m_Smooth12;
|
|
|
|
if (m_Smooth3 > 1)
|
|
m_Smooth3 = 1;
|
|
|
|
m_OptDir = std::copysign(T(1.0), m_Opt);
|
|
m_PetalsSign = std::copysign(T(1.0), m_K);
|
|
|
|
if (m_Opt3 < 0)
|
|
m_OptDir = -1;
|
|
|
|
if (m_OptDir > 0)
|
|
m_Ghost = 0;
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_L, prefix + "pRose3D_l", 1, eParamType::REAL_NONZERO));
|
|
m_Params.push_back(ParamWithName<T>(&m_K, prefix + "pRose3D_k", 3));
|
|
m_Params.push_back(ParamWithName<T>(&m_C, prefix + "pRose3D_c"));
|
|
m_Params.push_back(ParamWithName<T>(&m_Z1, prefix + "pRose3D_z1", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Z2, prefix + "pRose3D_z2", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_RefSc, prefix + "pRose3D_refSc", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Opt, prefix + "pRose3D_opt", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_OptSc, prefix + "pRose3D_optSc", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Opt3, prefix + "pRose3D_opt3"));
|
|
m_Params.push_back(ParamWithName<T>(&m_Transp, prefix + "pRose3D_transp", T(0.5)));
|
|
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "pRose3D_dist", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Wagsc, prefix + "pRose3D_wagsc", 0));
|
|
m_Params.push_back(ParamWithName<T>(&m_Crvsc, prefix + "pRose3D_crvsc", 0));
|
|
m_Params.push_back(ParamWithName<T>(&m_F, prefix + "pRose3D_f", 3));
|
|
m_Params.push_back(ParamWithName<T>(&m_Wigsc, prefix + "pRose3D_wigsc"));
|
|
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "pRose3D_offset"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Cycle, prefix + "pRose3D_cycle"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_OptDir, prefix + "pRose3D_opt_dir"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_PetalsSign, prefix + "pRose3D_petals_sign"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_NumPetals, prefix + "pRose3D_num_petals"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_AbsOptSc, prefix + "pRose3D_abs_optSc"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Smooth12, prefix + "pRose3D_smooth12"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Smooth3, prefix + "pRose3D_smooth3"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_AntiOpt1, prefix + "pRose3D_anti_opt1"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Ghost, prefix + "pRose3D_ghost"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Freq, prefix + "pRose3D_freq"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_WigScale, prefix + "pRose3D_wig_scale"));
|
|
}
|
|
|
|
private:
|
|
T m_L;
|
|
T m_K;
|
|
T m_C;
|
|
T m_Z1;
|
|
T m_Z2;
|
|
T m_RefSc;
|
|
T m_Opt;
|
|
T m_OptSc;
|
|
T m_Opt3;
|
|
T m_Transp;
|
|
T m_Dist;
|
|
T m_Wagsc;
|
|
T m_Crvsc;
|
|
T m_F;
|
|
T m_Wigsc;
|
|
T m_Offset;
|
|
T m_Cycle;//Precalc.
|
|
T m_OptDir;
|
|
T m_PetalsSign;
|
|
T m_NumPetals;
|
|
T m_AbsOptSc;
|
|
T m_Smooth12;
|
|
T m_Smooth3;
|
|
T m_AntiOpt1;
|
|
T m_Ghost;
|
|
T m_Freq;
|
|
T m_WigScale;
|
|
};
|
|
|
|
/// <summary>
|
|
/// log_db.
|
|
/// By DarkBeam, taken from JWildfire.
|
|
/// http://jwildfire.org/forum/viewtopic.php?f=23&t=1450&p=2692#p2692
|
|
/// </summary>
|
|
template <typename T>
|
|
class LogDBVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
LogDBVariation(T weight = 1.0) : ParametricVariation<T>("log_db", eVariationId::VAR_LOG_DB, weight, true, false, false, false, true)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(LogDBVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
int i, adp;
|
|
T atanPeriod = 0;
|
|
|
|
for (i = 0; i < 7; i++)
|
|
{
|
|
adp = rand.Rand(10) - 5;
|
|
|
|
if (std::abs(adp) >= 3)
|
|
adp = 0;
|
|
|
|
atanPeriod += adp;
|
|
}
|
|
|
|
atanPeriod *= m_FixPe;
|
|
helper.Out.x = m_Denom * std::log(helper.m_PrecalcSumSquares);
|
|
helper.Out.y = m_Weight * (helper.m_PrecalcAtanyx + atanPeriod);
|
|
helper.Out.z = m_Weight * helper.In.z;
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string base = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string fixPeriod = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string denom = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string fixPe = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\tint i, adp;\n"
|
|
<< "\t\treal_t atanPeriod = 0;\n"
|
|
<< "\n"
|
|
<< "\t\tfor (i = 0; i < 7; i++)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t adp = MwcNextRange(mwc, 10) - 5;\n"
|
|
<< "\n"
|
|
<< "\t\t if (abs(adp) >= 3)\n"
|
|
<< "\t\t adp = 0;\n"
|
|
<< "\n"
|
|
<< "\t\t atanPeriod += adp;\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\tatanPeriod *= " << fixPe << ";\n"
|
|
<< "\t\tvOut.x = " << denom << " * log(precalcSumSquares);\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (precalcAtanyx + atanPeriod);\n"
|
|
<< "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n"
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual void Precalc() override
|
|
{
|
|
m_Denom = T(0.5);
|
|
|
|
if (m_Base > EPS)
|
|
m_Denom = m_Denom / std::log(T(M_E) * m_Base);
|
|
|
|
m_Denom *= m_Weight;
|
|
m_FixPe = T(M_PI);
|
|
|
|
if (m_FixPeriod > EPS)
|
|
m_FixPe *= m_FixPeriod;
|
|
}
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Base, prefix + "log_db_base", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_FixPeriod, prefix + "log_db_fix_period", 1));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Denom, prefix + "log_db_denom"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_FixPe, prefix + "log_db_fix_pe"));
|
|
}
|
|
private:
|
|
T m_Base;
|
|
T m_FixPeriod;
|
|
T m_Denom;
|
|
T m_FixPe;
|
|
};
|
|
|
|
/// <summary>
|
|
/// circlesplit.
|
|
/// By tatasz.
|
|
/// http://fav.me/dapecsh
|
|
/// </summary>
|
|
template <typename T>
|
|
class CircleSplitVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
CircleSplitVariation(T weight = 1.0) : ParametricVariation<T>("circlesplit", eVariationId::VAR_CIRCLESPLIT, weight, true, true, false, false, true)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(CircleSplitVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T x1, y1;
|
|
|
|
if (helper.m_PrecalcSqrtSumSquares < (m_Radius - m_Split))
|
|
{
|
|
x1 = helper.In.x;
|
|
y1 = helper.In.y;
|
|
}
|
|
else
|
|
{
|
|
T a = helper.m_PrecalcAtanyx;
|
|
T len = helper.m_PrecalcSqrtSumSquares + m_Split;
|
|
x1 = std::cos(a) * len;
|
|
y1 = std::sin(a) * len;
|
|
}
|
|
|
|
helper.Out.x = m_Weight * x1;
|
|
helper.Out.y = m_Weight * y1;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string cs_radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string cs_split = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t x1, y1;\n"
|
|
<< "\n"
|
|
<< "\t\tif (precalcSqrtSumSquares < (" << cs_radius << " - " << cs_split << "))\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tx1 = vIn.x;\n"
|
|
<< "\t\t\ty1 = vIn.y;\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\treal_t a = precalcAtanyx;\n"
|
|
<< "\t\t\treal_t len = precalcSqrtSumSquares + " << cs_split << ";\n"
|
|
<< "\t\t\tx1 = cos(a) * len;\n"
|
|
<< "\t\t\ty1 = sin(a) * len;\n"
|
|
<< "\t\t}"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * x1;\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * y1;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Radius, prefix + "circlesplit_radius", 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Split, prefix + "circlesplit_split", T(0.5)));
|
|
}
|
|
|
|
private:
|
|
T m_Radius;
|
|
T m_Split;
|
|
};
|
|
|
|
/// <summary>
|
|
/// cylinder2.
|
|
/// By tatasz.
|
|
/// http://fav.me/dapecsh
|
|
/// </summary>
|
|
template <typename T>
|
|
class Cylinder2Variation : public Variation<T>
|
|
{
|
|
public:
|
|
Cylinder2Variation(T weight = 1.0) : Variation<T>("cylinder2", eVariationId::VAR_CYLINDER2, weight) { }
|
|
|
|
VARCOPY(Cylinder2Variation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
helper.Out.x = m_Weight * (helper.In.x / Zeps(std::sqrt(SQR(helper.In.x) + 1)));
|
|
helper.Out.y = m_Weight * helper.In.y;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss;
|
|
intmax_t varIndex = IndexInXform();
|
|
ss << "\t{\n"
|
|
<< "\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x / Zeps(sqrt(SQR(vIn.x) + (real_t)1.0)));\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps" };
|
|
}
|
|
};
|
|
|
|
/// <summary>
|
|
/// tile_log.
|
|
/// By zy0rg.
|
|
/// http://zy0rg.deviantart.com
|
|
/// </summary>
|
|
template <typename T>
|
|
class TileLogVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
TileLogVariation(T weight = 1.0) : ParametricVariation<T>("tile_log", eVariationId::VAR_TILE_LOG, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(TileLogVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T temp = Round(std::log(rand.Frand01<T>()) * (rand.Rand() & 1 ? m_Spread : -m_Spread));
|
|
helper.Out.x = m_Weight * (helper.In.x + temp);
|
|
helper.Out.y = m_Weight * helper.In.y;
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string spread = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t temp = (real_t) (Round(log(MwcNext01(mwc)) * (MwcNext(mwc) & 1 ? " << spread << " : -" << spread << ")));\n"
|
|
<< "\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + temp);\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Round" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Spread, prefix + "tile_log_spread", 1));
|
|
}
|
|
|
|
private:
|
|
T m_Spread;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Truchet_fill.
|
|
/// By tatasz.
|
|
/// http://fav.me/dapecsh
|
|
/// </summary>
|
|
template <typename T>
|
|
class TruchetFillVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
TruchetFillVariation(T weight = 1.0) : ParametricVariation<T>("Truchet_fill", eVariationId::VAR_TRUCHET_FILL, weight)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(TruchetFillVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T modbase = T(65535);
|
|
T multiplier = T(32747); //1103515245;
|
|
T offset = T(12345);
|
|
T x = helper.In.x * m_Scale;
|
|
T y = helper.In.y * m_Scale;
|
|
T intx = Round(x);
|
|
T inty = Round(y);
|
|
T r = x - intx;
|
|
|
|
if (r < 0)
|
|
x = 1 + r;
|
|
else
|
|
x = r;
|
|
|
|
r = y - inty;
|
|
|
|
if (r < 0)
|
|
y = 1 + r;
|
|
else
|
|
y = r;
|
|
|
|
T tiletype = 0;
|
|
|
|
if (m_Seed != 0)
|
|
{
|
|
if (m_Seed == 1)
|
|
{
|
|
tiletype = m_Seed;
|
|
}
|
|
else
|
|
{
|
|
T xrand = helper.In.x;
|
|
T yrand = helper.In.y;
|
|
xrand = Round(std::abs(xrand)) * m_Seed2;
|
|
yrand = Round(std::abs(yrand)) * m_Seed2;
|
|
T niter = xrand + yrand + (xrand * yrand);
|
|
T randint = (m_Seed + niter) * m_Seed2 * T(0.5);
|
|
randint = std::fmod((randint * multiplier + offset), modbase);
|
|
tiletype = std::fmod(randint, T(2.0));
|
|
}
|
|
}
|
|
|
|
T r0, r1;
|
|
|
|
if (tiletype < T(1))
|
|
{
|
|
//Slow drawmode
|
|
r0 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx);
|
|
r1 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y - 1), m_FinalExponent)), m_OneOverEx);
|
|
}
|
|
else
|
|
{
|
|
r0 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx);
|
|
r1 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y - T(1.0)), m_FinalExponent)), m_OneOverEx);
|
|
}
|
|
|
|
T x1, y1;
|
|
T r00 = fabs(r0 - T(0.5)) / m_Rmax;
|
|
|
|
if (r00 < 1)
|
|
{
|
|
x1 = 2 * (x + std::floor(helper.In.x));
|
|
y1 = 2 * (y + std::floor(helper.In.y));
|
|
}
|
|
else
|
|
{
|
|
x1 = 0;
|
|
y1 = 0;
|
|
}
|
|
|
|
T r11 = std::fabs(r1 - T(0.5)) / m_Rmax;
|
|
|
|
if (r11 < 1)
|
|
{
|
|
helper.Out.x = x1 + (2 * (x + std::floor(helper.In.x))) - helper.In.x;
|
|
helper.Out.y = y1 + (2 * (y + std::floor(helper.In.y))) - helper.In.y;
|
|
}
|
|
else
|
|
{
|
|
helper.Out.x = x1 - helper.In.x;
|
|
helper.Out.y = y1 - helper.In.y;
|
|
}
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0;
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string exponent = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string arcWidth = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string seed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string finalexponent = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string oneOverEx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string width = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string seed2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string rmax = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t modbase = 65535;\n"
|
|
<< "\t\treal_t multiplier = 32747;\n"
|
|
<< "\t\treal_t offset = 12345;\n"
|
|
<< "\n"
|
|
<< "\t\treal_t x = vIn.x * " << scale << ";\n"
|
|
<< "\t\treal_t y = vIn.y * " << scale << ";\n"
|
|
<< "\t\treal_t intx = Round(x);\n"
|
|
<< "\t\treal_t inty = Round(y);\n"
|
|
<< "\n"
|
|
<< "\t\treal_t r = x - intx;\n"
|
|
<< "\n"
|
|
<< "\t\tif (r < 0)\n"
|
|
<< "\t\t\tx = r + 1;\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t\tx = r;\n"
|
|
<< "\n"
|
|
<< "\t\tr = y - inty;\n"
|
|
<< "\n"
|
|
<< "\t\tif (r < 0)\n"
|
|
<< "\t\t\ty = r + 1;\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t\ty = r;\n"
|
|
<< "\n"
|
|
<< "\t\treal_t tiletype = 0;\n"
|
|
<< "\n"
|
|
<< "\t\tif (" << seed << " != 0)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tif (" << seed << " == 1)\n"
|
|
<< "\t\t\t{\n"
|
|
<< "\t\t\t\ttiletype = " << seed << ";\n"
|
|
<< "\t\t\t}\n"
|
|
<< "\t\t\telse\n"
|
|
<< "\t\t\t{\n"
|
|
<< "\t\t\t\treal_t xrand = vIn.x;\n"
|
|
<< "\t\t\t\treal_t yrand = vIn.y;\n"
|
|
<< "\n"
|
|
<< "\t\t\t\txrand = Round(fabs(xrand)) * " << seed2 << ";\n"
|
|
<< "\t\t\t\tyrand = Round(fabs(yrand)) * " << seed2 << ";\n"
|
|
<< "\n"
|
|
<< "\t\t\t\treal_t niter = xrand + yrand + (xrand * yrand);\n"
|
|
<< "\t\t\t\treal_t randint = (" << seed << " + niter) * " << seed2 << " * ((real_t) 0.5);\n"
|
|
<< "\n"
|
|
<< "\t\t\t\trandint = fmod((randint * multiplier + offset), modbase);\n"
|
|
<< "\t\t\t\ttiletype = fmod(randint, 2);\n"
|
|
<< "\t\t\t}\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\treal_t r0, r1;\n"
|
|
<< "\n"
|
|
<< "\t\tif (tiletype < 1)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tr0 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n"
|
|
<< "\t\t\tr1 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tr0 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n"
|
|
<< "\t\t\tr1 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\treal_t x1, y1;\n"
|
|
<< "\t\treal_t r00 = fabs(r0 - (real_t) 0.5) / " << rmax << ";\n"
|
|
<< "\n"
|
|
<< "\t\tif (r00 < 1.0)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tx1 = 2 * (x + floor(vIn.x));\n"
|
|
<< "\t\t\ty1 = 2 * (y + floor(vIn.y));\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tx1 = 0;\n"
|
|
<< "\t\t\ty1 = 0;\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\treal_t r11 = fabs(r1 - (real_t) 0.5) / " << rmax << ";\n"
|
|
<< "\n"
|
|
<< "\t\tif (r11 < 1)\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tvOut.x = x1 + (2 * (x + floor(vIn.x))) - vIn.x;\n"
|
|
<< "\t\t\tvOut.y = y1 + (2 * (y + floor(vIn.y))) - vIn.y;\n"
|
|
<< "\t\t}\n"
|
|
<< "\t\telse\n"
|
|
<< "\t\t{\n"
|
|
<< "\t\t\tvOut.x = x1 - vIn.x;\n"
|
|
<< "\t\t\tvOut.y = y1 - vIn.y;\n"
|
|
<< "\t\t}\n"
|
|
<< "\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Round" };
|
|
}
|
|
|
|
virtual void Precalc() override
|
|
{
|
|
m_FinalExponent = m_Exponent > T(2) ? T(2) : (m_Exponent < T(0.001) ? T(0.001) : m_Exponent);
|
|
m_OneOverEx = T(1) / m_FinalExponent;
|
|
m_Width = m_ArcWidth > T(1) ? T(1) : (m_ArcWidth < T(0.001) ? T(0.001) : m_ArcWidth);
|
|
m_Seed2 = std::sqrt(m_Seed * T(1.5)) / Zeps(m_Seed * T(0.5)) * T(0.25);
|
|
m_Rmax = T(0.5) * (std::pow(T(2), m_OneOverEx) - T(1)) * m_Width;
|
|
m_Scale = T(1) / m_Weight;
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Exponent, prefix + "Truchet_fill_exponent", 2, eParamType::REAL_CYCLIC, T(0.001), 2));
|
|
m_Params.push_back(ParamWithName<T>(&m_ArcWidth, prefix + "Truchet_fill_arc_width", T(0.5), eParamType::REAL_CYCLIC, T(0.001), 1));
|
|
m_Params.push_back(ParamWithName<T>(&m_Seed, prefix + "Truchet_fill_seed"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_FinalExponent, prefix + "Truchet_fill_final_exponent"));//Precalc
|
|
m_Params.push_back(ParamWithName<T>(true, &m_OneOverEx, prefix + "Truchet_fill_oneoverex"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Width, prefix + "Truchet_fill_width"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Seed2, prefix + "Truchet_fill_seed2"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Rmax, prefix + "Truchet_fill_rmax"));
|
|
m_Params.push_back(ParamWithName<T>(true, &m_Scale, prefix + "Truchet_fill_scale"));
|
|
}
|
|
|
|
private:
|
|
T m_Exponent;
|
|
T m_ArcWidth;
|
|
T m_Seed;
|
|
T m_FinalExponent;//Precalc.
|
|
T m_OneOverEx;
|
|
T m_Width;
|
|
T m_Seed2;
|
|
T m_Rmax;
|
|
T m_Scale;
|
|
};
|
|
|
|
/// <summary>
|
|
/// waves2_radial.
|
|
/// By tatasz.
|
|
/// http://fav.me/dapecsh
|
|
/// </summary>
|
|
template <typename T>
|
|
class Waves2RadialVariation : public ParametricVariation<T>
|
|
{
|
|
public:
|
|
Waves2RadialVariation(T weight = 1.0) : ParametricVariation<T>("waves2_radial", eVariationId::VAR_WAVES2_RADIAL, weight, true, true)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
PARVARCOPY(Waves2RadialVariation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T x0 = helper.In.x;
|
|
T y0 = helper.In.y;
|
|
T dist = helper.m_PrecalcSqrtSumSquares;
|
|
T factor = (dist < m_Distance) ? (dist - m_Null) / Zeps(m_Distance - m_Null) : T(1);
|
|
factor = (dist < m_Null) ? T(0) : factor;
|
|
helper.Out.x = m_Weight * (x0 + factor * std::sin(y0 * m_Freqx) * m_Scalex);
|
|
helper.Out.y = m_Weight * (y0 + factor * std::sin(x0 * m_Freqy) * m_Scaley);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t i = 0, varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
string freqX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scaleX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string freqY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string scaleY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string nullVar = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
string distance = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t x0 = vIn.x;\n"
|
|
<< "\t\treal_t y0 = vIn.y;\n"
|
|
<< "\n"
|
|
<< "\t\treal_t dist = precalcSqrtSumSquares;\n"
|
|
<< "\t\treal_t factor = (dist < " << distance << ") ? (dist - " << nullVar << ") / Zeps(" << distance << "-" << nullVar << ") : (real_t)(1.0);\n"
|
|
<< "\t\tfactor = (dist < " << nullVar << ") ? (real_t) 0.0 : factor;\n"
|
|
<< "\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (x0 + factor * sin(y0 * " << freqX << ") * " << scaleX << ");\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (y0 + factor * sin(x0 * " << freqY << ") * " << scaleY << ");\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
|
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
|
{
|
|
return vector<string> { "Zeps" };
|
|
}
|
|
|
|
protected:
|
|
void Init()
|
|
{
|
|
string prefix = Prefix();
|
|
m_Params.clear();
|
|
m_Params.push_back(ParamWithName<T>(&m_Freqx, prefix + "waves2_radial_freqx", 7));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scalex, prefix + "waves2_radial_scalex", T(0.1)));
|
|
m_Params.push_back(ParamWithName<T>(&m_Freqy, prefix + "waves2_radial_freqy", 13));
|
|
m_Params.push_back(ParamWithName<T>(&m_Scaley, prefix + "waves2_radial_scaley", T(0.1)));
|
|
m_Params.push_back(ParamWithName<T>(&m_Null, prefix + "waves2_radial_null", 2));
|
|
m_Params.push_back(ParamWithName<T>(&m_Distance, prefix + "waves2_radial_distance", 10));
|
|
}
|
|
|
|
private:
|
|
T m_Freqx;
|
|
T m_Scalex;
|
|
T m_Freqy;
|
|
T m_Scaley;
|
|
T m_Null;
|
|
T m_Distance;
|
|
};
|
|
|
|
/// <summary>
|
|
/// panorama1.
|
|
/// </summary>
|
|
template <typename T>
|
|
class Panorama1Variation : public Variation<T>
|
|
{
|
|
public:
|
|
Panorama1Variation(T weight = 1.0) : Variation<T>("panorama1", eVariationId::VAR_PANORAMA1, weight, true, false, false, false, false)
|
|
{
|
|
}
|
|
|
|
VARCOPY(Panorama1Variation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T aux = 1 / std::sqrt(helper.m_PrecalcSumSquares + 1);
|
|
T x1 = helper.m_TransX * aux;
|
|
T y1 = helper.m_TransY * aux;
|
|
aux = std::sqrt(x1 * x1 + y1 * y1);
|
|
helper.Out.x = m_Weight * std::atan2(x1, y1) * T(M_1_PI);
|
|
helper.Out.y = m_Weight * (aux - T(0.5));
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t aux = 1.0 / sqrt(precalcSumSquares + 1);\n"
|
|
<< "\t\treal_t x1 = transX * aux;\n"
|
|
<< "\t\treal_t y1 = transY * aux;\n"
|
|
<< "\t\taux = sqrt(x1 * x1 + y1 * y1);\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * atan2(x1, y1) * M1PI;\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (aux - 0.5);\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
/// <summary>
|
|
/// panorama2.
|
|
/// </summary>
|
|
template <typename T>
|
|
class Panorama2Variation : public Variation<T>
|
|
{
|
|
public:
|
|
Panorama2Variation(T weight = 1.0) : Variation<T>("panorama2", eVariationId::VAR_PANORAMA2, weight, true, true, false, false, false)
|
|
{
|
|
}
|
|
|
|
VARCOPY(Panorama2Variation)
|
|
|
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
|
{
|
|
T aux = 1 / (helper.m_PrecalcSqrtSumSquares + 1);
|
|
T x1 = helper.m_TransX * aux;
|
|
T y1 = helper.m_TransY * aux;
|
|
aux = std::sqrt(x1 * x1 + y1 * y1);
|
|
helper.Out.x = m_Weight * std::atan2(x1, y1) * T(M_1_PI);
|
|
helper.Out.y = m_Weight * (aux - T(0.5));
|
|
helper.Out.z = DefaultZ(helper);
|
|
}
|
|
|
|
virtual string OpenCLString() const override
|
|
{
|
|
ostringstream ss, ss2;
|
|
intmax_t varIndex = IndexInXform();
|
|
ss2 << "_" << XformIndexInEmber() << "]";
|
|
string index = ss2.str();
|
|
ss << "\t{\n"
|
|
<< "\t\treal_t aux = 1.0 / (precalcSqrtSumSquares + 1);\n"
|
|
<< "\t\treal_t x1 = transX * aux;\n"
|
|
<< "\t\treal_t y1 = transY * aux;\n"
|
|
<< "\t\taux = sqrt(x1 * x1 + y1 * y1);\n"
|
|
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * atan2(x1, y1) * M1PI;\n"
|
|
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (aux - 0.5);\n"
|
|
<< "\t\tvOut.z = " << DefaultZCl()
|
|
<< "\t}\n";
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D)
|
|
MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B)
|
|
MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN)
|
|
MAKEPREPOSTPARVAR(JacDn, jac_dn, JAC_DN)
|
|
MAKEPREPOSTPARVAR(JacSn, jac_sn, JAC_SN)
|
|
MAKEPREPOSTPARVAR(PressureWave, pressure_wave, PRESSURE_WAVE)
|
|
MAKEPREPOSTVAR(Gamma, gamma, GAMMA)
|
|
MAKEPREPOSTPARVAR(PRose3D, pRose3D, PROSE3D)
|
|
MAKEPREPOSTPARVAR(LogDB, log_db, LOG_DB)
|
|
MAKEPREPOSTPARVAR(CircleSplit, circlesplit, CIRCLESPLIT)
|
|
MAKEPREPOSTVAR(Cylinder2, cylinder2, CYLINDER2)
|
|
MAKEPREPOSTPARVAR(TileLog, tile_log, TILE_LOG)
|
|
MAKEPREPOSTPARVAR(TruchetFill, Truchet_fill, TRUCHET_FILL)
|
|
MAKEPREPOSTPARVAR(Waves2Radial, waves2_radial, WAVES2_RADIAL)
|
|
MAKEPREPOSTVAR(Panorama1, panorama1, PANORAMA1)
|
|
MAKEPREPOSTVAR(Panorama2, panorama2, PANORAMA2)
|
|
}
|