#pragma once #include "Variation.h" namespace EmberNs { /// /// Linear: /// nx = tx; /// ny = ty; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API LinearVariation : public Variation { public: LinearVariation(T weight = 1.0) : Variation("linear", VAR_LINEAR, weight) { } VARCOPY(LinearVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Sinusoidal: /// nx = sin(tx); /// ny = sin(ty); /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API SinusoidalVariation : public Variation { public: SinusoidalVariation(T weight = 1.0) : Variation("sinusoidal", VAR_SINUSOIDAL, weight) { } VARCOPY(SinusoidalVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * sin(helper.In.x); helper.Out.y = m_Weight * sin(helper.In.y); } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sin(vIn.x);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * sin(vIn.y);\n" << "\t}\n"; return ss.str(); } }; /// /// Spherical: /// T r2 = tx * tx + ty * ty + 1e-6; /// nx = tx / r2; /// ny = ty / r2; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API SphericalVariation : public Variation { public: SphericalVariation(T weight = 1.0) : Variation("spherical", VAR_SPHERICAL, weight, true) { } VARCOPY(SphericalVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r2 = m_Weight / (helper.m_PrecalcSumSquares + EPS6); helper.Out.x = r2 * helper.In.x; helper.Out.y = r2 * helper.In.y; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r2 = xform->m_VariationWeights[" << varIndex << "] / (precalcSumSquares + EPS6);\n" << "\n" << "\t\tvOut.x = r2 * vIn.x;\n" << "\t\tvOut.y = r2 * vIn.y;\n" << "\t}\n"; return ss.str(); } }; /// /// Swirl: /// double r2 = tx * tx + ty * ty; /// double c1 = sin(r2); /// double c2 = cos(r2); /// nx = c1 * tx - c2 * ty; /// ny = c2 * tx + c1 * ty; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API SwirlVariation : public Variation { public: SwirlVariation(T weight = 1.0) : Variation("swirl", VAR_SWIRL, weight, true) { } VARCOPY(SwirlVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T c1, c2; sincos(helper.m_PrecalcSumSquares, &c1, &c2); helper.Out.x = m_Weight * (c1 * helper.In.x - c2 * helper.In.y); helper.Out.y = m_Weight * (c2 * helper.In.x + c1 * helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t c1 = sin(precalcSumSquares);\n" << "\t\treal_t c2 = cos(precalcSumSquares);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (c1 * vIn.x - c2 * vIn.y);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (c2 * vIn.x + c1 * vIn.y);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Horseshoe: /// a = atan2(tx, ty); /// c1 = sin(a); /// c2 = cos(a); /// nx = c1 * tx - c2 * ty; /// ny = c2 * tx + c1 * ty; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API HorseshoeVariation : public Variation { public: HorseshoeVariation(T weight = 1.0) : Variation("horseshoe", VAR_HORSESHOE, weight, true, true) { } VARCOPY(HorseshoeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight / (helper.m_PrecalcSqrtSumSquares + T(EPS)); helper.Out.x = (helper.In.x - helper.In.y) * (helper.In.x + helper.In.y) * r; helper.Out.y = 2 * helper.In.x * helper.In.y * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / (precalcSqrtSumSquares + EPS);\n" << "\n" << "\t\tvOut.x = (vIn.x - vIn.y) * (vIn.x + vIn.y) * r;\n" << "\t\tvOut.y = 2.0 * vIn.x * vIn.y * r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Polar: /// nx = atan2(tx, ty) / M_PI; /// ny = sqrt(tx * tx + ty * ty) - 1.0; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API PolarVariation : public Variation { public: PolarVariation(T weight = 1.0) : Variation("polar", VAR_POLAR, weight, true, true, false, true, false) { } VARCOPY(PolarVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T nx = helper.m_PrecalcAtanxy * T(M_1_PI); T ny = helper.m_PrecalcSqrtSumSquares - 1; helper.Out.x = m_Weight * nx; helper.Out.y = m_Weight * ny; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * (precalcAtanxy * M_1_PI));\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * (precalcSqrtSumSquares - 1.0));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Handkerchief: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// p[0] += weight * sin(a + r) * r; /// p[1] += weight * cos(a - r) * r; /// template class EMBER_API HandkerchiefVariation : public Variation { public: HandkerchiefVariation(T weight = 1.0) : Variation("handkerchief", VAR_HANDKERCHIEF, weight, true, true, false, true) { } VARCOPY(HandkerchiefVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * helper.m_PrecalcSqrtSumSquares * sin(helper.m_PrecalcAtanxy + helper.m_PrecalcSqrtSumSquares); helper.Out.y = m_Weight * helper.m_PrecalcSqrtSumSquares * cos(helper.m_PrecalcAtanxy - helper.m_PrecalcSqrtSumSquares); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares * sin(precalcAtanxy + precalcSqrtSumSquares);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares * cos(precalcAtanxy - precalcSqrtSumSquares);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Heart: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// a *= r; /// p[0] += weight * sin(a) * r; /// p[1] += weight * cos(a) * -r; /// template class EMBER_API HeartVariation : public Variation { public: HeartVariation(T weight = 1.0) : Variation("heart", VAR_HEART, weight, true, true, false, true) { } VARCOPY(HeartVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.m_PrecalcSqrtSumSquares * helper.m_PrecalcAtanxy; T r = m_Weight * helper.m_PrecalcSqrtSumSquares; helper.Out.x = r * sin(a); helper.Out.y = (-r) * cos(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t a = precalcSqrtSumSquares * precalcAtanxy;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\n" << "\t\tvOut.x = r * sin(a);\n" << "\t\tvOut.y = (-r) * cos(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Disc: /// nx = tx * M_PI; /// ny = ty * M_PI; /// a = atan2(nx, ny); /// r = sqrt(nx * nx + ny * ny); /// p[0] += weight * sin(r) * a / M_PI; /// p[1] += weight * cos(r) * a / M_PI; /// template class EMBER_API DiscVariation : public ParametricVariation { public: DiscVariation(T weight = 1.0) : ParametricVariation("disc", VAR_DISC, weight, true, true, false, true) { Init(); } PARVARCOPY(DiscVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T val = T(M_PI) * helper.m_PrecalcSqrtSumSquares; T r = m_WeightByPI * helper.m_PrecalcAtanxy; helper.Out.x = sin(val) * r; helper.Out.y = cos(val) * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string weightByPI = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. ss << "\t{\n" << "\t\treal_t val = M_PI * precalcSqrtSumSquares;\n" << "\t\treal_t r = " << weightByPI << " * precalcAtanxy;\n" << "\n" << "\t\tvOut.x = sin(val) * r;\n" << "\t\tvOut.y = cos(val) * r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_WeightByPI = m_Weight * T(M_1_PI); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_WeightByPI, prefix + "disc_weight_by_pi"));//Precalcs only, no params. } private: T m_WeightByPI;//Precalcs only, no params. }; /// /// Spiral: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty) + 1e-6; /// p[0] += weight * (cos(a) + sin(r)) / r; /// p[1] += weight * (sin(a) - cos(r)) / r; /// template class EMBER_API SpiralVariation : public Variation { public: SpiralVariation(T weight = 1.0) : Variation("spiral", VAR_SPIRAL, weight, true, true, true) { } VARCOPY(SpiralVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSqrtSumSquares + T(EPS); T r1 = m_Weight / r; helper.Out.x = r1 * (helper.m_PrecalcCosa + sin(r)); helper.Out.y = r1 * (helper.m_PrecalcSina - cos(r)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = precalcSqrtSumSquares + EPS;\n" << "\t\treal_t r1 = xform->m_VariationWeights[" << varIndex << "] / r;\n" << "\n" << "\t\tvOut.x = r1 * (precalcCosa + sin(r));\n" << "\t\tvOut.y = r1 * (precalcSina - cos(r));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Hyperbolic: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty) + 1e-6; /// p[0] += weight * sin(a) / r; /// p[1] += weight * cos(a) * r; /// template class EMBER_API HyperbolicVariation : public Variation { public: HyperbolicVariation(T weight = 1.0) : Variation("hyperbolic", VAR_HYPERBOLIC, weight, true, true, true) { } VARCOPY(HyperbolicVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSqrtSumSquares + T(EPS); helper.Out.x = m_Weight * helper.m_PrecalcSina / r; helper.Out.y = m_Weight * helper.m_PrecalcCosa * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = precalcSqrtSumSquares + EPS;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * precalcSina / r;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcCosa * r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Diamond: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// p[0] += weight * sin(a) * cos(r); /// p[1] += weight * cos(a) * sin(r); /// template class EMBER_API DiamondVariation : public Variation { public: DiamondVariation(T weight = 1.0) : Variation("diamond", VAR_DIAMOND, weight, true, true, true) { } VARCOPY(DiamondVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * helper.m_PrecalcSina * cos(helper.m_PrecalcSqrtSumSquares); helper.Out.y = m_Weight * helper.m_PrecalcCosa * sin(helper.m_PrecalcSqrtSumSquares); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * precalcSina * cos(precalcSqrtSumSquares);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcCosa * sin(precalcSqrtSumSquares);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Ex: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// n0 = sin(a + r); /// n1 = cos(a - r); /// m0 = n0 * n0 * n0 * r; /// m1 = n1 * n1 * n1 * r; /// p[0] += weight * (m0 + m1); /// p[1] += weight * (m0 - m1); /// template class EMBER_API ExVariation : public Variation { public: ExVariation(T weight = 1.0) : Variation("ex", VAR_EX, weight, true, true, false, true) { } VARCOPY(ExVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.m_PrecalcAtanxy; T r = helper.m_PrecalcSqrtSumSquares; T n0 = sin(a + r); T n1 = cos(a - r); T m0 = n0 * n0 * n0 * r; T m1 = n1 * n1 * n1 * r; helper.Out.x = m_Weight * (m0 + m1); helper.Out.y = m_Weight * (m0 - m1); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t a = precalcAtanxy;\n" << "\t\treal_t r = precalcSqrtSumSquares;\n" << "\t\treal_t n0 = sin(a + r);\n" << "\t\treal_t n1 = cos(a - r);\n" << "\t\treal_t m0 = n0 * n0 * n0 * r;\n" << "\t\treal_t m1 = n1 * n1 * n1 * r;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (m0 + m1);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (m0 - m1);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Julia: /// a = atan2(tx, ty)/2.0; /// if (random bit()) a += M_PI; /// r = pow(tx*tx + ty*ty, 0.25); /// nx = r * cos(a); /// ny = r * sin(a); /// p[0] += v * nx; /// p[1] += v * ny; /// template class EMBER_API JuliaVariation : public Variation { public: JuliaVariation(T weight = 1.0) : Variation("julia", VAR_JULIA, weight, true, true, false, true) { } VARCOPY(JuliaVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight * sqrt(helper.m_PrecalcSqrtSumSquares); T a = T(0.5) * helper.m_PrecalcAtanxy; if (rand.RandBit()) a += T(M_PI); helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * sqrt(precalcSqrtSumSquares);\n" << "\t\treal_t a = 0.5 * precalcAtanxy;\n" << "\n" << "\t\tif (MwcNext(mwc) & 1)\n" << "\t\t a += M_PI;\n" << "\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Bent: /// nx = tx; /// ny = ty; /// if (nx < 0.0) nx = nx * 2.0; /// if (ny < 0.0) ny = ny / 2.0; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API BentVariation : public Variation { public: BentVariation(T weight = 1.0) : Variation("bent", VAR_BENT, weight) { } VARCOPY(BentVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T nx = helper.In.x < T(0.0) ? helper.In.x * 2 : helper.In.x; T ny = helper.In.y < T(0.0) ? helper.In.y / 2 : helper.In.y; helper.Out.x = m_Weight * nx; helper.Out.y = m_Weight * ny; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t nx = vIn.x < 0.0 ? (vIn.x * 2.0) : vIn.x;\n" << "\t\treal_t ny = vIn.y < 0.0 ? (vIn.y / 2.0) : vIn.y;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * nx;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * ny;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Waves: /// dx = coef[2][0]; /// dy = coef[2][1]; /// nx = tx + coef[1][0] * sin(ty / ((dx * dx) + EPS)); /// ny = ty + coef[1][1] * sin(tx / ((dy * dy) + EPS)); /// p[0] += weight * nx; /// p[1] += weight * ny; /// Special case here, use parametric for precalcs, but no regular params. /// template class EMBER_API WavesVariation : public ParametricVariation { public: WavesVariation(T weight = 1.0) : ParametricVariation("waves", VAR_WAVES, weight) { Init(); } PARVARCOPY(WavesVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T c10 = m_Xform->m_Affine.B(); T c11 = m_Xform->m_Affine.E(); T nx = helper.In.x + c10 * sin(helper.In.y * m_Dx2); T ny = helper.In.y + c11 * sin(helper.In.x * m_Dy2); helper.Out.x = m_Weight * nx; helper.Out.y = m_Weight * ny; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string dx2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalcs only, no params. string dy2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t c10 = xform->m_B;\n" << "\t\treal_t c11 = xform->m_E;\n" << "\t\treal_t nx = vIn.x + c10 * sin(vIn.y * " << dx2 << ");\n" << "\t\treal_t ny = vIn.y + c11 * sin(vIn.x * " << dy2 << ");\n" << "\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * nx);\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * ny);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { if (m_Xform)//If this variation exists by itself and hasn't been added to an xform yet, m_Xform will be NULL. { T dx = m_Xform->m_Affine.C(); T dy = m_Xform->m_Affine.F(); m_Dx2 = 1 / (dx * dx + T(EPS)); m_Dy2 = 1 / (dy * dy + T(EPS)); } } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_Dx2, prefix + "waves_dx2"));//Precalcs only, no params. m_Params.push_back(ParamWithName(true, &m_Dy2, prefix + "waves_dy2")); } private: T m_Dx2;//Precalcs only, no params. T m_Dy2; }; /// /// Fisheye: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// r = 2 * r / (r + 1); /// nx = r * cos(a); /// ny = r * sin(a); /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API FisheyeVariation : public Variation { public: FisheyeVariation(T weight = 1.0) : Variation("fisheye", VAR_FISHEYE, weight, true, true) { } VARCOPY(FisheyeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = 2 * m_Weight / (helper.m_PrecalcSqrtSumSquares + 1); helper.Out.x = r * helper.In.y; helper.Out.y = r * helper.In.x; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = 2 * xform->m_VariationWeights[" << varIndex << "] / (precalcSqrtSumSquares + 1);\n" << "\n" << "\t\tvOut.x = r * vIn.y;\n" << "\t\tvOut.y = r * vIn.x;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Popcorn: /// dx = tan(3 * ty); /// dy = tan(3 * tx); /// nx = tx + coef[2][0] * sin(dx); /// ny = ty + coef[2][1] * sin(dy); /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API PopcornVariation : public Variation { public: PopcornVariation(T weight = 1.0) : Variation("popcorn", VAR_POPCORN, weight) { } VARCOPY(PopcornVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T dx = tan(3 * helper.In.y); T dy = tan(3 * helper.In.x); T nx = helper.In.x + m_Xform->m_Affine.C() * sin(dx); T ny = helper.In.y + m_Xform->m_Affine.F() * sin(dy); helper.Out.x = m_Weight * nx; helper.Out.y = m_Weight * ny; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t dx = tan(3 * vIn.y);\n" << "\t\treal_t dy = tan(3 * vIn.x);\n" << "\t\treal_t nx = vIn.x + xform->m_C * sin(dx);\n" << "\t\treal_t ny = vIn.y + xform->m_F * sin(dy);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * nx;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * ny;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Exponential: /// dx = exp(tx - 1.0); /// dy = M_PI * ty; /// nx = cos(dy) * dx; /// ny = sin(dy) * dx; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API ExponentialVariation : public Variation { public: ExponentialVariation(T weight = 1.0) : Variation("exponential", VAR_EXPONENTIAL, weight) { } VARCOPY(ExponentialVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T dx = m_Weight * exp(helper.In.x - 1); T dy = T(M_PI) * helper.In.y; helper.Out.x = dx * cos(dy); helper.Out.y = dx * sin(dy); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t dx = xform->m_VariationWeights[" << varIndex << "] * exp(vIn.x - 1.0);\n" << "\t\treal_t dy = M_PI * vIn.y;\n" << "\n" << "\t\tvOut.x = dx * cos(dy);\n" << "\t\tvOut.y = dx * sin(dy);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Power: /// a = atan2(tx, ty); /// sa = sin(a); /// r = sqrt(tx * tx + ty * ty); /// r = pow(r, sa); /// nx = r * precalc_cosa; /// ny = r * sa; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API PowerVariation : public Variation { public: PowerVariation(T weight = 1.0) : Variation("power", VAR_POWER, weight, true, true, true) { } VARCOPY(PowerVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight * pow(helper.m_PrecalcSqrtSumSquares, helper.m_PrecalcSina); 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() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSqrtSumSquares, precalcSina);\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(); } }; /// /// Cosine: /// nx = cos(tx * M_PI) * cosh(ty); /// ny = -sin(tx * M_PI) * sinh(ty); /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API CosineVariation : public Variation { public: CosineVariation(T weight = 1.0) : Variation("cosine", VAR_COSINE, weight) { } VARCOPY(CosineVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.In.x * T(M_PI); T nx = cos(a) * cosh(helper.In.y); T ny = -sin(a) * sinh(helper.In.y); helper.Out.x = m_Weight * nx; helper.Out.y = m_Weight * ny; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t a = vIn.x * M_PI;\n" << "\t\treal_t nx = cos(a) * cosh(vIn.y);\n" << "\t\treal_t ny = -sin(a) * sinh(vIn.y);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * nx;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * ny;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Rings: /// dx = coef[2][0]; /// dx = dx * dx + EPS; /// r = sqrt(tx * tx + ty * ty); /// r = fmod(r + dx, 2 * dx) - dx + r * (1 - dx); /// a = atan2(tx, ty); /// nx = cos(a) * r; /// ny = sin(a) * r; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API RingsVariation : public Variation { public: RingsVariation(T weight = 1.0) : Variation("rings", VAR_RINGS, weight, true, true, true) { } VARCOPY(RingsVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T dx = m_Xform->m_Affine.C() * m_Xform->m_Affine.C() + T(EPS); T r = helper.m_PrecalcSqrtSumSquares; r = m_Weight * (fmod(r + dx, 2 * dx) - dx + r * (1 - dx)); 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() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t dx = xform->m_C * xform->m_C + EPS;\n" << "\t\treal_t r = precalcSqrtSumSquares;\n" << "\n" << "\t\tr = xform->m_VariationWeights[" << varIndex << "] * (fmod(r + dx, 2 * dx) - dx + r * (1 - dx));\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(); } }; /// /// Fan: /// dx = coef[2][0]; /// dy = coef[2][1]; /// dx = M_PI * (dx * dx + EPS); /// dx2 = dx / 2; /// a = atan(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// a += (fmod(a + dy, dx) > dx2) ? -dx2 : dx2; /// nx = cos(a) * r; /// ny = sin(a) * r; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API FanVariation : public Variation { public: FanVariation(T weight = 1.0) : Variation("fan", VAR_FAN, weight, true, true, false, true) { } VARCOPY(FanVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T dx = T(M_PI) * (m_Xform->m_Affine.C() * m_Xform->m_Affine.C() + T(EPS)); T dy = m_Xform->m_Affine.F(); T dx2 = T(0.5) * dx; T a = helper.m_PrecalcAtanxy; T r = m_Weight * helper.m_PrecalcSqrtSumSquares; a += (fmod(a + dy, dx) > dx2) ? -dx2 : dx2; helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t dx = M_PI * (xform->m_C * xform->m_C + EPS);\n" << "\t\treal_t dy = xform->m_F;\n" << "\t\treal_t dx2 = 0.5 * dx;\n" << "\t\treal_t a = precalcAtanxy + ((fmod(precalcAtanxy + dy, dx) > dx2) ? -dx2 : dx2);\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Blob: /// a = atan2(tx, ty); /// r = sqrt(tx * tx + ty * ty); /// r = r * (bloblow + (blobhigh - bloblow) * (0.5 + 0.5 * sin(blobwaves * a))); /// nx = sin(a) * r; /// ny = cos(a) * r; /// /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API BlobVariation : public ParametricVariation { public: BlobVariation(T weight = 1.0) : ParametricVariation("blob", VAR_BLOB, weight, true, true, true, true) { Init(); } PARVARCOPY(BlobVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSqrtSumSquares * (m_BlobLow + m_BlobDiff * (T(0.5) + T(0.5) * sin(m_BlobWaves * helper.m_PrecalcAtanxy))); helper.Out.x = m_Weight * helper.m_PrecalcSina * r; helper.Out.y = m_Weight * helper.m_PrecalcCosa * r; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string blobLow = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string blobHigh = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string blobWaves = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string blobDiff = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r = precalcSqrtSumSquares * (" << blobLow << " + " << blobDiff << " * (0.5 + 0.5 * sin(" << blobWaves << " * precalcAtanxy)));\n" << "\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * precalcSina * r);\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * precalcCosa * r);\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_BlobDiff = m_BlobHigh - m_BlobLow; } virtual void Random(QTIsaac& rand) { m_BlobLow = T(0.2) + T(0.5) * rand.Frand01(); m_BlobHigh = T(0.8) + T(0.4) * rand.Frand01(); m_BlobWaves = (T)(int)(2 + 5 * rand.Frand01()); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_BlobLow, prefix + "blob_low")); m_Params.push_back(ParamWithName(&m_BlobHigh, prefix + "blob_high", 1)); m_Params.push_back(ParamWithName(&m_BlobWaves, prefix + "blob_waves", 1)); m_Params.push_back(ParamWithName(true, &m_BlobDiff, prefix + "blob_diff"));//Precalc. } private: T m_BlobLow; T m_BlobHigh; T m_BlobWaves; T m_BlobDiff;//Precalc. }; /// /// Pdj: /// nx1 = cos(pdjb * tx); /// nx2 = sin(pdjc * tx); /// ny1 = sin(pdja * ty); /// ny2 = cos(pdjd * ty); /// /// p[0] += weight * (ny1 - nx1); /// p[1] += weight * (nx2 - ny2); /// template class EMBER_API PdjVariation : public ParametricVariation { public: PdjVariation(T weight = 1.0) : ParametricVariation("pdj", VAR_PDJ, weight) { Init(); } PARVARCOPY(PdjVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T nx1 = cos(m_PdjB * helper.In.x); T nx2 = sin(m_PdjC * helper.In.x); T ny1 = sin(m_PdjA * helper.In.y); T ny2 = cos(m_PdjD * helper.In.y); helper.Out.x = m_Weight * (ny1 - nx1); helper.Out.y = m_Weight * (nx2 - ny2); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string pdjA = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pdjB = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pdjC = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pdjD = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t nx1 = cos(" << pdjB << " * vIn.x)" << ";\n" << "\t\treal_t nx2 = sin(" << pdjC << " * vIn.x)" << ";\n" << "\t\treal_t ny1 = sin(" << pdjA << " * vIn.y)" << ";\n" << "\t\treal_t ny2 = cos(" << pdjD << " * vIn.y)" << ";\n" << "\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * (ny1 - nx1));\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * (nx2 - ny2));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_PdjA = 3 * rand.Frand11(); m_PdjB = 3 * rand.Frand11(); m_PdjC = 3 * rand.Frand11(); m_PdjD = 3 * rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_PdjA, prefix + "pdj_a")); m_Params.push_back(ParamWithName(&m_PdjB, prefix + "pdj_b")); m_Params.push_back(ParamWithName(&m_PdjC, prefix + "pdj_c")); m_Params.push_back(ParamWithName(&m_PdjD, prefix + "pdj_d")); } private: T m_PdjA; T m_PdjB; T m_PdjC; T m_PdjD; }; /// /// Fan2: /// a = precalc_atan; /// r = precalc_sqrt; /// /// dy = fan2y; /// dx = M_PI * (fan2x * fan2x + EPS); /// dx2 = dx / 2.0; /// /// t = a + dy - dx * (int)((a + dy) / dx); /// /// if (t > dx2) /// a = a - dx2; /// else /// a = a + dx2; /// /// nx = sin(a) * r; /// ny = cos(a) * r; /// /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API Fan2Variation : public ParametricVariation { public: Fan2Variation(T weight = 1.0) : ParametricVariation("fan2", VAR_FAN2, weight, true, true, false, true) { Init(); } PARVARCOPY(Fan2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.m_PrecalcAtanxy; T r = m_Weight * helper.m_PrecalcSqrtSumSquares; T t = a + m_Fan2Y - m_Fan2Dx * (int)((a + m_Fan2Y) / m_Fan2Dx); if (t > m_Fan2Dx2) a = a - m_Fan2Dx2; else a = a + m_Fan2Dx2; helper.Out.x = r * sin(a); helper.Out.y = r * cos(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string fan2X = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string fan2Y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string dx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string dx2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = precalcAtanxy;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\t\treal_t t = a + " << fan2Y << " - " << dx << " * (int)((a + " << fan2Y << ") / " << dx << ");\n" << "\n" << "\t\tif (t > " << dx2 << ")\n" << "\t\t a = a - " << dx2 << ";\n" << "\t\telse\n" << "\t\t a = a + " << dx2 << ";\n" << "\n" << "\t\tvOut.x = r * sin(a);\n" << "\t\tvOut.y = r * cos(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Fan2Dx = T(M_PI) * (SQR(m_Fan2X) + EPS); m_Fan2Dx2 = T(0.5) * m_Fan2Dx; } virtual void Random(QTIsaac& rand) { m_Fan2X = rand.Frand11(); m_Fan2Y = rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Fan2X, prefix + "fan2_x")); m_Params.push_back(ParamWithName(&m_Fan2Y, prefix + "fan2_y")); m_Params.push_back(ParamWithName(true, &m_Fan2Dx, prefix + "fan2_dx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Fan2Dx2, prefix + "fan2_dx2")); } private: T m_Fan2X; T m_Fan2Y; T m_Fan2Dx;//Precalc. T m_Fan2Dx2; }; /// /// Rings2: /// r = precalc_sqrt; /// dx = rings2val * rings2val + EPS; /// r += dx - 2.0 * dx * (int)((r + dx)/(2.0 * dx)) - dx + r * (1.0 - dx); /// nx = precalc_sina * r; /// ny = precalc_cosa * r; /// p[0] += weight * nx; /// p[1] += weight * ny; /// template class EMBER_API Rings2Variation : public ParametricVariation { public: Rings2Variation(T weight = 1.0) : ParametricVariation("rings2", VAR_RINGS2, weight, true, true, true) { Init(); } PARVARCOPY(Rings2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSqrtSumSquares; r += -2 * m_Rings2Val2 * (int)((r + m_Rings2Val2) / (2 * m_Rings2Val2)) + r * (1 - m_Rings2Val2); helper.Out.x = m_Weight * helper.m_PrecalcSina * r; helper.Out.y = m_Weight * helper.m_PrecalcCosa * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string rings2Val = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rings2Val2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r = precalcSqrtSumSquares;\n" << "\n" << "\t\tr += -2.0 * " << rings2Val2 << " * (int)((r + " << rings2Val2 << ") / (2.0 * " << rings2Val2 << ")) + r * (1.0 - " << rings2Val2 << ");\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * precalcSina * r);\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * precalcCosa * r);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Rings2Val2 = SQR(m_Rings2Val) + EPS; } virtual void Random(QTIsaac& rand) { m_Rings2Val = 2 * rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Rings2Val, prefix + "rings2_val", 1));//This differs from the original which used zero. Use 1 instead to avoid getting too close to dividing by zero. m_Params.push_back(ParamWithName(true, &m_Rings2Val2, prefix + "rings2_val2"));//Precalc. } private: T m_Rings2Val; T m_Rings2Val2;//Precalc. }; /// /// Eyefish: /// r = 2.0 * weight / (precalc_sqrt + 1.0); /// p[0] += r * tx; /// p[1] += r * ty; /// template class EMBER_API EyefishVariation : public Variation { public: EyefishVariation(T weight = 1.0) : Variation("eyefish", VAR_EYEFISH, weight, true, true) { } VARCOPY(EyefishVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = 2 * m_Weight / (helper.m_PrecalcSqrtSumSquares + 1); helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = (xform->m_VariationWeights[" << varIndex << "] * 2.0) / (precalcSqrtSumSquares + 1.0);\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Bubble. /// template class EMBER_API BubbleVariation : public Variation { public: BubbleVariation(T weight = 1.0) : Variation("bubble", VAR_BUBBLE, weight, true) { } VARCOPY(BubbleVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight / (T(0.25) * helper.m_PrecalcSumSquares + 1); helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / (0.25 * precalcSumSquares + 1);\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cylinder. /// template class EMBER_API CylinderVariation : public Variation { public: CylinderVariation(T weight = 1.0) : Variation("cylinder", VAR_CYLINDER, weight) { } VARCOPY(CylinderVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * sin(helper.In.x); helper.Out.y = m_Weight * helper.In.y; helper.Out.z = m_Weight * cos(helper.In.x); } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sin(vIn.x);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * cos(vIn.x);\n" << "\t}\n"; return ss.str(); } }; /// /// Perspective. /// template class EMBER_API PerspectiveVariation : public ParametricVariation { public: PerspectiveVariation(T weight = 1.0) : ParametricVariation("perspective", VAR_PERSPECTIVE, weight) { Init(); } PARVARCOPY(PerspectiveVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T d = m_Dist - helper.In.y * m_Vsin; if (d == 0) d = EPS6; T t = 1 / d; helper.Out.x = m_Weight * m_Dist * helper.In.x * t; helper.Out.y = m_Weight * m_VfCos * helper.In.y * t; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vSin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string vfCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t d = " << dist << " - vIn.y * " << vSin << ";\n" << "\n" << "\t\tif (d == 0)\n" << "\t\t d = EPS6;\n" << "\n" << "\t\treal_t t = 1.0 / d;\n" << "\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * " << dist << " * vIn.x * t);\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * " << vfCos << " * vIn.y * t);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { T angle = m_Angle * T(M_PI) / 2; m_Vsin = sin(angle); m_VfCos = m_Dist * cos(angle); } virtual void Random(QTIsaac& rand) { m_Angle = rand.Frand01(); m_Dist = 2 * rand.Frand01() + 1; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "perspective_angle"));//Params. m_Params.push_back(ParamWithName(&m_Dist, prefix + "perspective_dist")); m_Params.push_back(ParamWithName(true, &m_Vsin, prefix + "perspective_vsin"));//Precalc. m_Params.push_back(ParamWithName(true, &m_VfCos, prefix + "perspective_vfcos")); } private: T m_Angle;//Params. T m_Dist; T m_Vsin;//Precalc. T m_VfCos; }; /// /// Noise. /// template class EMBER_API NoiseVariation : public Variation { public: NoiseVariation(T weight = 1.0) : Variation("noise", VAR_NOISE, weight) { } VARCOPY(NoiseVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tempr = rand.Frand01() * M_2PI; T r = m_Weight * rand.Frand01(); helper.Out.x = helper.In.x * r * cos(tempr); helper.Out.y = helper.In.y * r * sin(tempr); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tempr = MwcNext01(mwc) * M_2PI;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc);\n" << "\n" << "\t\tvOut.x = vIn.x * r * cos(tempr);\n" << "\t\tvOut.y = vIn.y * r * sin(tempr);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// JuliaN. /// template class EMBER_API JuliaNGenericVariation : public ParametricVariation { public: JuliaNGenericVariation(T weight = 1.0) : ParametricVariation("julian", VAR_JULIAN, weight, true, false, false, false, true) { Init(); } PARVARCOPY(JuliaNGenericVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tempr = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand((ISAAC_INT)m_Rn)) / m_Power; T r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn); helper.Out.x = r * cos(tempr); helper.Out.y = r * sin(tempr); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tint tRnd = (int)(" << rn << " * MwcNext01(mwc));\n" << "\t\treal_t tempr = (precalcAtanyx + M_2PI * tRnd) / " << power << ";\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << ");\n" << "\n" << "\t\tvOut.x = r * cos(tempr);\n" << "\t\tvOut.y = r * sin(tempr);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Rn = fabs(m_Power); m_Cn = m_Dist / m_Power / 2; } virtual void Random(QTIsaac& rand) { m_Dist = 1; m_Power = (T)(int)(5 * rand.Frand01() + 2); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Dist, prefix + "julian_dist", 1));//Params. m_Params.push_back(ParamWithName(&m_Power, prefix + "julian_power", 1, INTEGER_NONZERO)); m_Params.push_back(ParamWithName(true, &m_Rn, prefix + "julian_rn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "julian_cn")); } private: T m_Dist;//Params. T m_Power; T m_Rn;//Precalc. T m_Cn; }; /// /// JuliaScope. /// template class EMBER_API JuliaScopeVariation : public ParametricVariation { public: JuliaScopeVariation(T weight = 1.0) : ParametricVariation("juliascope", VAR_JULIASCOPE, weight, true, false, false, false, true) { Init(); } PARVARCOPY(JuliaScopeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { int rnd = (int)(m_Rn * rand.Frand01()); T tempr, r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn); if ((rnd & 1) == 0) tempr = (M_2PI * rnd + helper.m_PrecalcAtanyx) / m_Power; else tempr = (M_2PI * rnd - helper.m_PrecalcAtanyx) / m_Power; helper.Out.x = r * cos(tempr); helper.Out.y = r * sin(tempr); helper.Out.z = m_Weight * helper.In.z; //int rnd = (int)(m_Rn * rand.Frand01()); //T tempr, r; //if ((rnd & 1) == 0) // tempr = (2 * T(M_PI) * (int)(m_Rn * rand.Frand01()) + helper.m_PrecalcAtanyx) / m_Power;//Fixed to get new random rather than use rnd from above.//SMOULDER //else // tempr = (2 * T(M_PI) * (int)(m_Rn * rand.Frand01()) - helper.m_PrecalcAtanyx) / m_Power; //r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn); //helper.Out.x = r * cos(tempr); //helper.Out.y = r * sin(tempr); } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tint rnd = (int)(" << rn << " * MwcNext01(mwc));\n" << "\t\treal_t tempr, r;\n" << "\n" << "\t\tif ((rnd & 1) == 0)\n" << "\t\t tempr = (M_2PI * rnd + precalcAtanyx) / " << power << ";\n" << "\t\telse\n" << "\t\t tempr = (M_2PI * rnd - precalcAtanyx) / " << power << ";\n" << "\n" << "\t\tr = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << ");\n" << "\n" << "\t\tvOut.x = r * cos(tempr);\n" << "\t\tvOut.y = r * sin(tempr);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; //ss << "\t{\n" // << "\t\tint rnd = (int)(" << rn << " * MwcNext01(mwc));\n" // << "\t\treal_t tempr, r;\n" // << "\n" // << "\t\tif ((rnd & 1) == 0)\n" // << "\t\t tempr = (2 * M_PI * (int)(" << rn << " * MwcNext01(mwc)) + precalcAtanyx) / " << power << ";\n"//Fixed to get new random rather than use rnd from above.//SMOULDER // << "\t\telse\n" // << "\t\t tempr = (2 * M_PI * (int)(" << rn << " * MwcNext01(mwc)) - precalcAtanyx) / " << power << ";\n" // << "\n" // << "\t\tr = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << ");\n" // << "\n" // << "\t\tvOut.x = r * cos(tempr);\n" // << "\t\tvOut.y = r * sin(tempr);\n" // << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" // << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Rn = fabs(m_Power); m_Cn = m_Dist / m_Power / 2; } virtual void Random(QTIsaac& rand) { m_Dist = 1; m_Power = (T)(int)(5 * rand.Frand01() + 2); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Dist, prefix + "juliascope_dist", 1));//Params. m_Params.push_back(ParamWithName(&m_Power, prefix + "juliascope_power", 1)); m_Params.push_back(ParamWithName(true, &m_Rn, prefix + "juliascope_rn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "juliascope_cn")); } private: T m_Dist;//Params. T m_Power; T m_Rn;//Precalc. T m_Cn; }; /// /// Blur. /// template class EMBER_API BlurVariation : public Variation { public: BlurVariation(T weight = 1.0) : Variation("blur", VAR_BLUR, weight) { } VARCOPY(BlurVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tempr = rand.Frand01() * M_2PI; T r = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2); helper.Out.x = r * cos(tempr); helper.Out.y = r * sin(tempr); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tmpr = MwcNext01(mwc) * M_2PI;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc);\n" << "\n" << "\t\tvOut.x = r * cos(tmpr);\n" << "\t\tvOut.y = r * sin(tmpr);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Gaussian blur. /// template class EMBER_API GaussianBlurVariation : public Variation { public: GaussianBlurVariation(T weight = 1.0) : Variation("gaussian_blur", VAR_GAUSSIAN_BLUR, weight) { } VARCOPY(GaussianBlurVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T angle = rand.Frand01() * M_2PI; T r = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2); helper.Out.x = r * cos(angle); helper.Out.y = r * sin(angle); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, 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" << "\n" << "\t\tvOut.x = r * cos(angle);\n" << "\t\tvOut.y = r * sin(angle);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Radial blur. /// template class EMBER_API RadialBlurVariation : public ParametricVariation { public: RadialBlurVariation(T weight = 1.0) : ParametricVariation("radial_blur", VAR_RADIAL_BLUR, weight, true, true, false, false, true) { Init(); } PARVARCOPY(RadialBlurVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { //Get pseudo-gaussian. T rndG = m_Weight * (rand.Frand01() + rand.Frand01() + rand.Frand01() + rand.Frand01() - 2); //Calculate angle & zoom. T ra = helper.m_PrecalcSqrtSumSquares; T tempa = helper.m_PrecalcAtanyx + m_Spin * rndG; T rz = m_Zoom * rndG - 1; helper.Out.x = ra * cos(tempa) + rz * helper.In.x; helper.Out.y = ra * sin(tempa) + rz * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string spin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string zoom = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t rndG = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) + MwcNext01(mwc) - 2.0);\n" << "\t\treal_t ra = precalcSqrtSumSquares;\n" << "\t\treal_t tempa = precalcAtanyx + "<< spin << " * rndG;\n" << "\t\treal_t rz = " << zoom << " * rndG - 1;\n" << "\n" << "\t\tvOut.x = ra * cos(tempa) + rz * vIn.x;\n" << "\t\tvOut.y = ra * sin(tempa) + rz * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { sincos(m_Angle * T(M_PI) / 2, &m_Spin, &m_Zoom); } virtual void Random(QTIsaac& rand) { m_Angle = (2 * rand.Frand01() - 1); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "radial_blur_angle"));//Params. m_Params.push_back(ParamWithName(true, &m_Spin, prefix + "radial_blur_spin"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Zoom, prefix + "radial_blur_zoom")); } private: T m_Angle;//Params. T m_Spin;//Precalc. T m_Zoom; }; /// /// Pie. /// template class EMBER_API PieVariation : public ParametricVariation { public: PieVariation(T weight = 1.0) : ParametricVariation("pie", VAR_PIE, weight) { Init(); } PARVARCOPY(PieVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { int sl = (int)(rand.Frand01() * m_Slices + T(0.5)); T a = m_Rotation + M_2PI * (sl + rand.Frand01() * m_Thickness) / m_Slices; T r = m_Weight * rand.Frand01(); helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rotation = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tint sl = (int)(MwcNext01(mwc) * " << slices << " + 0.5);\n" << "\t\treal_t a = " << rotation << " + M_2PI * (sl + MwcNext01(mwc) * " << thickness << ") / " << slices << ";\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc);\n" << "\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Params[0].Set(10 * rand.Frand01());//Slices. m_Params[1].Set(M_2PI * rand.Frand11());//Rotation. m_Thickness = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Slices, prefix + "pie_slices", 6, INTEGER_NONZERO, 1)); m_Params.push_back(ParamWithName(&m_Rotation, prefix + "pie_rotation", T(0.5), REAL_CYCLIC, 0, M_2PI)); m_Params.push_back(ParamWithName(&m_Thickness, prefix + "pie_thickness", T(0.5), REAL, 0, 1)); } private: T m_Slices; T m_Rotation; T m_Thickness; }; /// /// Ngon. /// template class EMBER_API NgonVariation : public ParametricVariation { public: NgonVariation(T weight = 1.0) : ParametricVariation("ngon", VAR_NGON, weight, true, false, false, false, true) { Init(); } PARVARCOPY(NgonVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T rFactor = pow(helper.m_PrecalcSumSquares, m_Power / 2); T theta = helper.m_PrecalcAtanyx; T b = M_2PI / m_Sides; T amp, phi = theta - (b * Floor(theta / b)); if (phi > b / 2) phi -= b; amp = m_Corners * (1 / (cos(phi) + EPS) - 1) + m_Circle; amp /= (rFactor + T(EPS)); helper.Out.x = m_Weight * helper.In.x * amp; helper.Out.y = m_Weight * helper.In.y * amp; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string sides = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string circle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string corners = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t rFactor = pow(precalcSumSquares, " << power << " / 2.0);\n" << "\t\treal_t theta = precalcAtanyx;\n" << "\t\treal_t b = M_2PI / " << sides << ";\n" << "\t\treal_t amp, phi = theta - (b * floor(theta / b));\n" << "\n" << "\t\tif (phi > b / 2)\n" << "\t\t phi -= b;\n" << "\n" << "\t\tamp = " << corners << " * (1.0 / (cos(phi) + EPS) - 1.0) + " << circle << ";\n" << "\t\tamp /= (rFactor + EPS);\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * vIn.x * amp);\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * vIn.y * amp);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Sides = (T)(int)(rand.Frand01() * 10 + 3); m_Power = 3 * rand.Frand01() + 1; m_Circle = 3 * rand.Frand01(); m_Corners = 2 * rand.Frand01() * m_Circle; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Sides, prefix + "ngon_sides", 5, INTEGER_NONZERO)); m_Params.push_back(ParamWithName(&m_Power, prefix + "ngon_power", 3)); m_Params.push_back(ParamWithName(&m_Circle, prefix + "ngon_circle", 1)); m_Params.push_back(ParamWithName(&m_Corners, prefix + "ngon_corners", 2)); } private: T m_Sides; T m_Power; T m_Circle; T m_Corners; }; /// /// Curl. /// template class EMBER_API CurlVariation : public ParametricVariation { public: CurlVariation(T weight = 1.0) : ParametricVariation("curl", VAR_CURL, weight) { Init(); } PARVARCOPY(CurlVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T re = 1 + m_C1w * helper.In.x + m_C2w * (SQR(helper.In.x) - SQR(helper.In.y));//Optimized from PostCurl. T im = m_C1w * helper.In.y + m_C22 * helper.In.x * helper.In.y; T r = SQR(re) + SQR(im); if (r == 0) r = EPS6; helper.Out.x = (helper.In.x * re + helper.In.y * im) / r; helper.Out.y = (helper.In.y * re - helper.In.x * im) / r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string c1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c1w = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c2w = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c22 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = vIn.x;\n" << "\t\treal_t y = vIn.y;\n" << "\t\treal_t re = 1 + " << c1w << " * x + " << c2w << " * (SQR(x) - SQR(y));\n" << "\t\treal_t im = " << c1w << " * y + " << c22 << " * x * y;\n" << "\t\treal_t r = SQR(re) + SQR(im);\n" << "\n" << "\t\tif (r == 0)\n" << "\t\t r = EPS6;\n" << "\n" << "\t\tvOut.x = (x * re + y * im) / r;\n" << "\t\tvOut.y = (y * re - x * im) / r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_C1w = m_C1 * m_Weight; m_C2w = m_C2 * m_Weight; m_C22 = 2 * m_C2w; } virtual void Random(QTIsaac& rand) { m_C1 = rand.Frand01(); m_C2 = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_C1, prefix + "curl_c1", 1)); m_Params.push_back(ParamWithName(&m_C2, prefix + "curl_c2")); m_Params.push_back(ParamWithName(true, &m_C1w, prefix + "curl_c1w"));//Precalc. m_Params.push_back(ParamWithName(true, &m_C2w, prefix + "curl_c2w")); m_Params.push_back(ParamWithName(true, &m_C22, prefix + "curl_c22")); } private: T m_C1; T m_C2; T m_C1w;//Precalc. T m_C2w; T m_C22; }; /// /// Rectangles. /// template class EMBER_API RectanglesVariation : public ParametricVariation { public: RectanglesVariation(T weight = 1.0) : ParametricVariation("rectangles", VAR_RECTANGLES, weight) { Init(); } PARVARCOPY(RectanglesVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (m_X == 0) helper.Out.x = m_Weight * helper.In.x; else helper.Out.x = m_Weight * ((2 * Floor(helper.In.x / m_X) + 1) * m_X - helper.In.x); if (m_Y == 0) helper.Out.y = m_Weight * helper.In.y; else helper.Out.y = m_Weight * ((2 * Floor(helper.In.y / m_Y) + 1) * m_Y - helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int 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\tif (" << x << " == 0)\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\telse\n" << "\t\t vOut.x = (xform->m_VariationWeights[" << varIndex << "] * ((2 * floor(vIn.x / " << x << ") + 1) * " << x << " - vIn.x));\n" << "\n" << "\t\tif (" << y << " == 0)\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\telse\n" << "\t\t vOut.y = (xform->m_VariationWeights[" << varIndex << "] * ((2 * floor(vIn.y / " << y << ") + 1) * " << y << " - vIn.y));\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_X = rand.Frand01(); m_Y = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "rectangles_x", 1)); m_Params.push_back(ParamWithName(&m_Y, prefix + "rectangles_y", 1)); } private: T m_X; T m_Y; }; /// /// Arch. /// template class EMBER_API ArchVariation : public Variation { public: ArchVariation(T weight = 1.0) : Variation("arch", VAR_ARCH, weight) { } VARCOPY(ArchVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T angle = rand.Frand01() * m_Weight * T(M_PI); T sinr, cosr; sincos(angle, &sinr, &cosr); helper.Out.x = m_Weight * sinr; helper.Out.y = m_Weight * (sinr * sinr) / cosr; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t angle = MwcNext01(mwc) * xform->m_VariationWeights[" << varIndex << "] * M_PI;\n" << "\t\treal_t sinr = sin(angle);\n" << "\t\treal_t cosr = cos(angle);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sinr;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (sinr * sinr) / cosr;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Tangent. /// template class EMBER_API TangentVariation : public Variation { public: TangentVariation(T weight = 1.0) : Variation("tangent", VAR_TANGENT, weight) { } VARCOPY(TangentVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * sin(helper.In.x) / cos(helper.In.y); helper.Out.y = m_Weight * tan(helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sin(vIn.x) / cos(vIn.y);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * tan(vIn.y);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Square. /// template class EMBER_API SquareVariation : public Variation { public: SquareVariation(T weight = 1.0) : Variation("square", VAR_SQUARE, weight) { } VARCOPY(SquareVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * (rand.Frand01() - T(0.5)); helper.Out.y = m_Weight * (rand.Frand01() - T(0.5)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) - 0.5);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) - 0.5);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Rays. /// template class EMBER_API RaysVariation : public Variation { public: RaysVariation(T weight = 1.0) : Variation("rays", VAR_RAYS, weight, true) { } VARCOPY(RaysVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T ang = m_Weight * rand.Frand01() * T(M_PI); T r = m_Weight / (helper.m_PrecalcSumSquares + T(EPS)); T tanr = m_Weight * tan(ang) * r; helper.Out.x = tanr * cos(helper.In.x); helper.Out.y = tanr * sin(helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t ang = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc) * M_PI;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] / (precalcSumSquares + EPS);\n" << "\t\treal_t tanr = xform->m_VariationWeights[" << varIndex << "] * tan(ang) * r;\n" << "\n" << "\t\tvOut.x = tanr * cos(vIn.x);\n" << "\t\tvOut.y = tanr * sin(vIn.y);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Blade. /// template class EMBER_API BladeVariation : public Variation { public: BladeVariation(T weight = 1.0) : Variation("blade", VAR_BLADE, weight, true, true) { } VARCOPY(BladeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = rand.Frand01() * m_Weight * helper.m_PrecalcSqrtSumSquares; T sinr, cosr; sincos(r, &sinr, &cosr); helper.Out.x = m_Weight * helper.In.x * (cosr + sinr); helper.Out.y = m_Weight * helper.In.x * (cosr - sinr); } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = MwcNext01(mwc) * xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\t\treal_t sinr = sin(r);\n" << "\t\treal_t cosr = cos(r);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x * (cosr + sinr);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.x * (cosr - sinr);\n" << "\t}\n"; return ss.str(); } }; /// /// Secant2. /// template class EMBER_API Secant2Variation : public Variation { public: Secant2Variation(T weight = 1.0) : Variation("secant2", VAR_SECANT2, weight, true, true) { } VARCOPY(Secant2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight * helper.m_PrecalcSqrtSumSquares; T cr = cos(r); T icr = 1 / cr; helper.Out.x = m_Weight * helper.In.x; if (cr < 0) helper.Out.y = m_Weight * (icr + 1); else helper.Out.y = m_Weight * (icr - 1); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\t\treal_t cr = cos(r);\n" << "\t\treal_t icr = 1.0 / cr;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\n" << "\t\tif (cr < 0.0)\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (icr + 1.0);\n" << "\t\telse\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (icr - 1.0);\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// TwinTrian. /// template class EMBER_API TwinTrianVariation : public Variation { public: TwinTrianVariation(T weight = 1.0) : Variation("TwinTrian", VAR_TWINTRIAN, weight, true, true) { } VARCOPY(TwinTrianVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = rand.Frand01() * m_Weight * helper.m_PrecalcSqrtSumSquares; T sinr, cosr, diff; sincos(r, &sinr, &cosr); diff = log10(sinr * sinr) + cosr; if (BadVal(diff)) diff = -30.0; helper.Out.x = m_Weight * helper.In.x * diff; helper.Out.y = m_Weight * helper.In.x * (diff - sinr * T(M_PI)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t r = MwcNext01(mwc) * xform->m_VariationWeights[" << varIndex << "] * precalcSqrtSumSquares;\n" << "\t\treal_t sinr = sin(r);\n" << "\t\treal_t cosr = cos(r);\n" << "\t\treal_t diff = log10(sinr * sinr) + cosr;\n" << "\n" << "\t\tif (BadVal(diff))\n" << "\t\t diff = -30.0;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x * diff;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.x * (diff - sinr * M_PI);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cross. /// template class EMBER_API CrossVariation : public Variation { public: CrossVariation(T weight = 1.0) : Variation("cross", VAR_CROSS, weight) { } VARCOPY(CrossVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T s = helper.In.x * helper.In.x - helper.In.y * helper.In.y; T r = m_Weight * sqrt(1 / (s * s + EPS)); helper.Out.x = helper.In.x * r; helper.Out.y = helper.In.y * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t s = vIn.x * vIn.x - vIn.y * vIn.y;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * sqrt(1.0 / (s * s + EPS));\n" << "\n" << "\t\tvOut.x = vIn.x * r;\n" << "\t\tvOut.y = vIn.y * r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Disc2. /// template class EMBER_API Disc2Variation : public ParametricVariation { public: Disc2Variation(T weight = 1.0) : ParametricVariation("disc2", VAR_DISC2, weight, false, false, false, true) { Init(); } PARVARCOPY(Disc2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r, t, sinr, cosr; t = m_RotTimesPi * (helper.In.x + helper.In.y); sincos(t, &sinr, &cosr); r = m_Weight * helper.m_PrecalcAtanxy / T(M_PI); helper.Out.x = (sinr + m_CosAdd) * r; helper.Out.y = (cosr + m_SinAdd) * r; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string rot = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string twist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string sinAdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cosAdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rotTimesPi = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t t = " << rotTimesPi << " * (vIn.x + vIn.y);\n" << "\t\treal_t sinr = sin(t);\n" << "\t\treal_t cosr = cos(t);\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * precalcAtanxy / M_PI;\n" << "\n" << "\t\tvOut.x = (sinr + " << cosAdd << ") * r;\n" << "\t\tvOut.y = (cosr + " << sinAdd << ") * r;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { T k, add = m_Twist; m_RotTimesPi = m_Rot * T(M_PI); sincos(add, &m_SinAdd, &m_CosAdd); m_CosAdd -= 1; if (add > 2 * M_PI) { k = (1 + add - 2 * T(M_PI)); m_CosAdd *= k; m_SinAdd *= k; } if (add < -2 * M_PI) { k = (1 + add + 2 * T(M_PI)); m_CosAdd *= k; m_SinAdd *= k; } } virtual void Random(QTIsaac& rand) { m_Rot = T(0.5) * rand.Frand01(); m_Twist = T(0.5) * rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Rot, prefix + "disc2_rot"));//Params. m_Params.push_back(ParamWithName(&m_Twist, prefix + "disc2_twist")); m_Params.push_back(ParamWithName(true, &m_SinAdd, prefix + "disc2_sin_add"));//Precalc. m_Params.push_back(ParamWithName(true, &m_CosAdd, prefix + "disc2_cos_add")); m_Params.push_back(ParamWithName(true, &m_RotTimesPi, prefix + "disc2_rot_times_pi")); } private: T m_Rot;//Params. T m_Twist; T m_SinAdd;//Precalc. T m_CosAdd; T m_RotTimesPi; }; /// /// SuperShape. /// template class EMBER_API SuperShapeVariation : public ParametricVariation { public: SuperShapeVariation(T weight = 1.0) : ParametricVariation("super_shape", VAR_SUPER_SHAPE, weight, true, true, false, false, true) { Init(); } PARVARCOPY(SuperShapeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T theta = m_Pm4 * helper.m_PrecalcAtanyx + T(M_PI_4); T t1 = fabs(cos(theta)); t1 = pow(t1, m_N2); T t2 = fabs(sin(theta)); t2 = pow(t2, m_N3); T r = m_Weight * ((m_Rnd * rand.Frand01() + (1 - m_Rnd) * helper.m_PrecalcSqrtSumSquares) - m_Holes) * pow(t1 + t2, m_PNeg1N1) / helper.m_PrecalcSqrtSumSquares; helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string m = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string n1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string n2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string n3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rnd = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string holes = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string pm4 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string pNeg1N1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t theta = " << pm4 << " * precalcAtanyx + M_PI_4;\n" << "\t\treal_t t1 = fabs(cos(theta));\n" << "\t\tt1 = pow(t1, " << n2 << ");\n" << "\t\treal_t t2 = fabs(sin(theta));\n" << "\t\tt2 = pow(t2, " << n3 << ");\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * ((" << rnd << " * MwcNext01(mwc) + (1.0 - " << rnd << ") * precalcSqrtSumSquares) - " << holes << ") * pow(t1 + t2, " << pNeg1N1 << ") / precalcSqrtSumSquares;\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Pm4 = m_M / T(4.0); m_PNeg1N1 = T(-1.0) / m_N1; } virtual void Random(QTIsaac& rand) { m_Rnd = rand.Frand01(); m_M = (T)(int)(rand.Frand01() * 6); m_N1 = rand.Frand01() * 40; m_N2 = rand.Frand01() * 20; m_N3 = m_N2; m_Holes = 0.0; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_M, prefix + "super_shape_m"));//Params. m_Params.push_back(ParamWithName(&m_N1, prefix + "super_shape_n1", 1)); m_Params.push_back(ParamWithName(&m_N2, prefix + "super_shape_n2", 1)); m_Params.push_back(ParamWithName(&m_N3, prefix + "super_shape_n3", 1)); m_Params.push_back(ParamWithName(&m_Rnd, prefix + "super_shape_rnd")); m_Params.push_back(ParamWithName(&m_Holes, prefix + "super_shape_holes")); m_Params.push_back(ParamWithName(true, &m_Pm4, prefix + "super_shape_pm4"));//Precalc. m_Params.push_back(ParamWithName(true, &m_PNeg1N1, prefix + "super_shape_pneg1n1")); } private: T m_M;//Params. T m_N1; T m_N2; T m_N3; T m_Rnd; T m_Holes; T m_Pm4;//Precalc. T m_PNeg1N1; }; /// /// Flower. /// template class EMBER_API FlowerVariation : public ParametricVariation { public: FlowerVariation(T weight = 1.0) : ParametricVariation("flower", VAR_FLOWER, weight, true, true, false, false, true) { Init(); } PARVARCOPY(FlowerVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T theta = helper.m_PrecalcAtanyx; T r = m_Weight * (rand.Frand01() - m_Holes) * cos(m_Petals * theta) / helper.m_PrecalcSqrtSumSquares; helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string petals = "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 r = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) - " << holes << ") * cos(" << petals << " * theta) / precalcSqrtSumSquares;\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Petals = 4 * rand.Frand01(); m_Holes = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Petals, prefix + "flower_petals")); m_Params.push_back(ParamWithName(&m_Holes, prefix + "flower_holes")); } private: T m_Petals; T m_Holes; }; /// /// Conic. /// template class EMBER_API ConicVariation : public ParametricVariation { public: ConicVariation(T weight = 1.0) : ParametricVariation("conic", VAR_CONIC, weight, true, true) { Init(); } PARVARCOPY(ConicVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T ct = helper.In.x / helper.m_PrecalcSqrtSumSquares; T r = m_Weight * (rand.Frand01() - m_Holes) * m_Eccentricity / (1 + m_Eccentricity * ct) / helper.m_PrecalcSqrtSumSquares; helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string eccentricity = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string holes = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t ct = vIn.x / precalcSqrtSumSquares;\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * (MwcNext01(mwc) - " << holes << ") * " << eccentricity << " / (1 + " << eccentricity << " * ct) / precalcSqrtSumSquares;\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * vIn.y;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Eccentricity = rand.Frand01(); m_Holes = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Eccentricity, prefix + "conic_eccentricity", 1)); m_Params.push_back(ParamWithName(&m_Holes, prefix + "conic_holes")); } private: T m_Eccentricity; T m_Holes; }; /// /// Parabola. /// template class EMBER_API ParabolaVariation : public ParametricVariation { public: ParabolaVariation(T weight = 1.0) : ParametricVariation("parabola", VAR_PARABOLA, weight, true, true) { Init(); } PARVARCOPY(ParabolaVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T sr, cr; sincos(helper.m_PrecalcSqrtSumSquares, &sr, &cr); helper.Out.x = m_Height * m_Weight * sr * sr * rand.Frand01(); helper.Out.y = m_Width * m_Weight * cr * rand.Frand01(); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string height = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string width = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t sr = sin(precalcSqrtSumSquares);\n" << "\t\treal_t cr = cos(precalcSqrtSumSquares);\n" << "\n" << "\t\tvOut.x = " << height << " * (xform->m_VariationWeights[" << varIndex << "] * sr * sr * MwcNext01(mwc));\n" << "\t\tvOut.y = " << width << " * (xform->m_VariationWeights[" << varIndex << "] * cr * MwcNext01(mwc));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Height = T(0.5) * rand.Frand01(); m_Width = T(0.5) * rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Height, prefix + "parabola_height")); m_Params.push_back(ParamWithName(&m_Width, prefix + "parabola_width")); } private: T m_Height; T m_Width; }; /// /// Bent2. /// template class EMBER_API Bent2Variation : public ParametricVariation { public: Bent2Variation(T weight = 1.0) : ParametricVariation("bent2", VAR_BENT2, weight) { Init(); } PARVARCOPY(Bent2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (helper.In.x >= 0) helper.Out.x = m_Weight * helper.In.x; else helper.Out.x = m_Vx * helper.In.x; if (helper.In.y >= 0) helper.Out.y = m_Weight * helper.In.y; else helper.Out.y = m_Vy * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int 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 vx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vy = "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;\n" << "\t\telse\n" << "\t\t vOut.x = " << vx << " * vIn.x;\n" << "\n" << "\t\tif (vIn.y >= 0)\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\telse\n" << "\t\tvOut.y = " << vy << " * vIn.y;\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Vx = m_X * m_Weight; m_Vy = m_Y * m_Weight; } virtual void Random(QTIsaac& rand) { m_X = 3 * (T(-0.5) + rand.Frand01()); m_Y = 3 * (T(-0.5) + rand.Frand01()); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "bent2_x", 1));//Params. m_Params.push_back(ParamWithName(&m_Y, prefix + "bent2_y", 1)); m_Params.push_back(ParamWithName(true, &m_Vx, prefix + "bent2_vx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Vy, prefix + "bent2_vy")); } private: T m_X;//Params. T m_Y; T m_Vx;//Precalc. T m_Vy; }; /// /// Bipolar. /// template class EMBER_API BipolarVariation : public ParametricVariation { public: BipolarVariation(T weight = 1.0) : ParametricVariation("bipolar", VAR_BIPOLAR, weight, true) { Init(); } PARVARCOPY(BipolarVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T x2y2 = helper.m_PrecalcSumSquares; T t = x2y2 + 1; T x2 = 2 * helper.In.x; T y = T(0.5) * atan2(2 * helper.In.y, x2y2 - 1) + m_S; if (y > T(M_PI_2)) y = T(-M_PI_2) + fmod(y + T(M_PI_2), T(M_PI)); else if (y < T(-M_PI_2)) y = T(M_PI_2) - fmod(T(M_PI_2) - y, T(M_PI)); T f = t + x2; T g = t - x2; if ((g == 0) || (f / g <= 0)) { if (m_VarType == VARTYPE_REG) { helper.Out.x = 0; helper.Out.y = 0; helper.Out.z = 0; } else { helper.Out.x = helper.In.x; helper.Out.y = helper.In.y; helper.Out.z = helper.In.z; } } else { helper.Out.x = m_V4 * log((t + x2) / (t - x2)); helper.Out.y = m_V * y; helper.Out.z = m_Weight * helper.In.z; } } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string shift = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string s = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string v = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string v4 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x2y2 = precalcSumSquares;\n" << "\t\treal_t t = x2y2 + 1;\n" << "\t\treal_t x2 = 2 * vIn.x;\n" << "\t\treal_t ps = " << s << ";\n" << "\t\treal_t y = 0.5 * atan2(2.0 * vIn.y, x2y2 - 1.0) + ps;\n" << "\n" << "\t\tif (y > M_PI_2)\n" << "\t\t y = -M_PI_2 + fmod(y + M_PI_2, M_PI);\n" << "\t\telse if (y < -M_PI_2)\n" << "\t\t y = M_PI_2 - fmod(M_PI_2 - y, M_PI);\n" << "\n" << "\t\treal_t f = t + x2;\n" << "\t\treal_t g = t - x2;\n" << "\n"; if (m_VarType == VARTYPE_REG) { ss << "\t\tif ((g == 0) || (f / g <= 0))\n" << "\t\t{\n" << "\t\t vOut.x = 0;\n" << "\t\t vOut.y = 0;\n" << "\t\t vOut.z = 0;\n" << "\t\t}\n"; } else { ss << "\t\tif ((g == 0) || (f / g <= 0))\n" << "\t\t{\n" << "\t\t vOut.x = vIn.x;\n" << "\t\t vOut.y = vIn.y;\n" << "\t\t vOut.z = vIn.z;\n" << "\t\t}\n"; } ss << "\t\telse\n" << "\t\t{\n" << "\t\t vOut.x = (" << v4 << " * log((t + x2) / (t - x2)));\n" << "\t\t vOut.y = (" << v << " * y);\n" << "\t\t vOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t\t}\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_S = T(-M_PI_2) * m_Shift;; m_V = m_Weight * T(M_2_PI); m_V4 = m_Weight * T(0.25) * T(M_2_PI); } virtual void Random(QTIsaac& rand) { m_Shift = 2 * rand.Frand01() - 1; } virtual bool SetParamVal(const char* name, T val) { if (!strcmp(name, "bipolar_shift")) { T temp = Fabsmod(T(0.5) * (val + 1)); m_Shift = 2 * temp - 1; Precalc(); return true; } return ParametricVariation::SetParamVal(name, val); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Shift, prefix + "bipolar_shift"));//Params. m_Params.push_back(ParamWithName(true, &m_S, prefix + "bipolar_s"));//Precalc. m_Params.push_back(ParamWithName(true, &m_V, prefix + "bipolar_v")); m_Params.push_back(ParamWithName(true, &m_V4, prefix + "bipolar_v4")); } private: T m_Shift;//Params. T m_S;//Precalc. T m_V; T m_V4; }; /// /// Boarders. /// template class EMBER_API BoardersVariation : public Variation { public: BoardersVariation(T weight = 1.0) : Variation("boarders", VAR_BOARDERS, weight) { } VARCOPY(BoardersVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T roundX = Rint(helper.In.x); T roundY = Rint(helper.In.y); T offsetX = helper.In.x - roundX; T offsetY = helper.In.y - roundY; if (rand.Frand01() >= 0.75) { helper.Out.x = m_Weight * (offsetX * T(0.5) + roundX); helper.Out.y = m_Weight * (offsetY * T(0.5) + roundY); } else { if (fabs(offsetX) >= fabs(offsetY)) { if (offsetX >= 0.0) { helper.Out.x = m_Weight * (offsetX * T(0.5) + roundX + T(0.25)); helper.Out.y = m_Weight * (offsetY * T(0.5) + roundY + T(0.25) * offsetY / offsetX); } else { helper.Out.x = m_Weight * (offsetX * T(0.5) + roundX - T(0.25)); helper.Out.y = m_Weight * (offsetY * T(0.5) + roundY - T(0.25) * offsetY / offsetX); } } else { if (offsetY >= 0.0) { helper.Out.y = m_Weight * (offsetY * T(0.5) + roundY + T(0.25)); helper.Out.x = m_Weight * (offsetX * T(0.5) + roundX + offsetX / offsetY * T(0.25)); } else { helper.Out.y = m_Weight * (offsetY * T(0.5) + roundY - T(0.25)); helper.Out.x = m_Weight * (offsetX * T(0.5) + roundX - offsetX / offsetY * T(0.25)); } } } helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t roundX = Rint(vIn.x);\n" << "\t\treal_t roundY = Rint(vIn.y);\n" << "\t\treal_t offsetX = vIn.x - roundX;\n" << "\t\treal_t offsetY = vIn.y - roundY;\n" << "\n" << "\t\tif (MwcNext01(mwc) >= 0.75)\n" << "\t\t{\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * 0.5 + roundX);\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * 0.5 + 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.0)\n" << "\t\t {\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * 0.5 + roundX + 0.25);\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * 0.5 + roundY + 0.25 * offsetY / offsetX);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * 0.5 + roundX - 0.25);\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * 0.5 + roundY - 0.25 * offsetY / offsetX);\n" << "\t\t }\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t if (offsetY >= 0.0)\n" << "\t\t {\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * 0.5 + roundY + 0.25);\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * 0.5 + roundX + offsetX / offsetY * 0.25);\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (offsetY * 0.5 + roundY - 0.25);\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetX * 0.5 + roundX - offsetX / offsetY * 0.25);\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(); } }; /// /// Butterfly. /// template class EMBER_API ButterflyVariation : public Variation { public: ButterflyVariation(T weight = 1.0) : Variation("butterfly", VAR_BUTTERFLY, weight) { } VARCOPY(ButterflyVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T wx = m_Weight * T(1.3029400317411197908970256609023);//This precision came from the original. T y2 = helper.In.y * 2; T r = wx * sqrt(fabs(helper.In.y * helper.In.x) / (T(EPS) + helper.In.x * helper.In.x + y2 * y2)); helper.Out.x = r * helper.In.x; helper.Out.y = r * y2; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t wx = xform->m_VariationWeights[" << varIndex << "] * 1.3029400317411197908970256609023;\n" << "\t\treal_t y2 = vIn.y * 2.0;\n" << "\t\treal_t r = wx * sqrt(fabs(vIn.y * vIn.x) / (EPS + vIn.x * vIn.x + y2 * y2));\n" << "\n" << "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.y = r * y2;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cell. /// template class EMBER_API CellVariation : public ParametricVariation { public: CellVariation(T weight = 1.0) : ParametricVariation("cell", VAR_CELL, weight) { Init(); } PARVARCOPY(CellVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T invCellSize = 1 / m_Size; T x = floor(helper.In.x * invCellSize);//Calculate input cell. Note that int cast is omitted here. See below. T y = floor(helper.In.y * invCellSize); T dx = helper.In.x - x * m_Size;//Offset from cell origin. T dy = helper.In.y - y * m_Size; //Interleave cells. if (y >= 0) { if (x >= 0) { y *= 2; x *= 2; } else { y *= 2; x = -(2 * x + 1); } } else { if (x >= 0) { y = -(2 * y + 1); x *= 2; } else { y = -(2 * y + 1); x = -(2 * x + 1); } } helper.Out.x = m_Weight * (dx + x * m_Size); helper.Out.y = -(m_Weight * (dy + y * m_Size)); helper.Out.z = m_Weight * helper.In.z; } /// /// Cell is very strange and will not run using integers. /// When using floats, it at least gives some output, however /// that output is slightly different than the CPU. But not by enough /// to change the shape of the final image. /// virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string size = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t invCellSize = 1.0 / " << size << ";\n" //Float to int, orig. //<< "\t\tint x = (int)floor(vIn.x * invCellSize);\n" //<< "\t\tint y = (int)floor(vIn.y * invCellSize);\n" //For some reason, OpenCL renders nothing if these are ints, so use floats. //Note that Cuburn also omits the usage of ints. << "\t\treal_t x = floor(vIn.x * invCellSize);\n" << "\t\treal_t y = floor(vIn.y * invCellSize);\n" << "\t\treal_t dx = vIn.x - x * " << size << ";\n" << "\t\treal_t dy = vIn.y - y * " << size << ";\n" << "\n" << "\t\tif (y >= 0)\n" << "\t\t{\n" << "\t\t if (x >= 0)\n" << "\t\t {\n" << "\t\t y *= 2;\n" << "\t\t x *= 2;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t y *= 2;\n" << "\t\t x = -(2 * x + 1);\n" << "\t\t }\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t if (x >= 0)\n" << "\t\t {\n" << "\t\t y = -(2 * y + 1);\n" << "\t\t x *= 2;\n" << "\t\t }\n" << "\t\t else\n" << "\t\t {\n" << "\t\t y = -(2 * y + 1);\n" << "\t\t x = -(2 * x + 1);\n" << "\t\t }\n" << "\t\t}\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (dx + x * " << size << ");\n" << "\t\tvOut.y = -(xform->m_VariationWeights[" << varIndex << "] * (dy + y * " << size << "));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Size = 2 * rand.Frand01() + T(0.5); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Size, prefix + "cell_size", 1)); } private: T m_Size; }; /// /// Cpow. /// template class EMBER_API CpowVariation : public ParametricVariation { public: CpowVariation(T weight = 1.0) : ParametricVariation("cpow", VAR_CPOW, weight, true, false, false, false, true) { Init(); } PARVARCOPY(CpowVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.m_PrecalcAtanyx; T lnr = T(0.5) * log(helper.m_PrecalcSumSquares); T angle = m_C * a + m_D * lnr + m_Ang * Floor(m_Power * rand.Frand01()); T m = m_Weight * exp(m_C * lnr - m_D * a); helper.Out.x = m * cos(angle); helper.Out.y = m * sin(angle); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string powerR = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string powerI = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ang = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = precalcAtanyx;\n" << "\t\treal_t lnr = 0.5 * log(precalcSumSquares);\n" << "\t\treal_t angle = " << c << " * a + " << d << " * lnr + " << ang << " * floor(" << power << " * MwcNext01(mwc));\n" << "\t\treal_t m = xform->m_VariationWeights[" << varIndex << "] * exp(" << c << " * lnr - " << d << " * a);\n" << "\n" << "\t\tvOut.x = m * cos(angle);\n" << "\t\tvOut.y = m * sin(angle);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_C = m_PowerR / m_Power; m_D = m_PowerI / m_Power; m_Ang = 2 * T(M_PI) / m_Power; } virtual void Random(QTIsaac& rand) { m_PowerR = 3 * rand.Frand01(); m_PowerI = rand.Frand01() - T(0.5); m_Params[2].Set(5 * rand.Frand01());//Power. } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_PowerR, prefix + "cpow_r", 1));//Params. m_Params.push_back(ParamWithName(&m_PowerI, prefix + "cpow_i")); m_Params.push_back(ParamWithName(&m_Power, prefix + "cpow_power", 1, INTEGER_NONZERO)); m_Params.push_back(ParamWithName(true, &m_C, prefix + "cpow_c"));//Precalc. m_Params.push_back(ParamWithName(true, &m_D, prefix + "cpow_d")); m_Params.push_back(ParamWithName(true, &m_Ang, prefix + "cpow_ang")); } private: T m_PowerR;//Params. T m_PowerI; T m_Power; T m_C;//Precalc. T m_D; T m_Ang; }; /// /// Curve. /// template class EMBER_API CurveVariation : public ParametricVariation { public: CurveVariation(T weight = 1.0) : ParametricVariation("curve", VAR_CURVE, weight) { Init(); } PARVARCOPY(CurveVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * helper.In.x + m_XAmpV * exp(-helper.In.y * helper.In.y * m_XLengthV); helper.Out.y = m_Weight * helper.In.y + m_YAmpV * exp(-helper.In.x * helper.In.x * m_YLengthV); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string xAmp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yAmp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yLength = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xAmpV = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yAmpV = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xLengthV = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yLengthV = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x + " << xAmpV << " * exp(-vIn.y * vIn.y * " << xLengthV << ");\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y + " << yAmpV << " * exp(-vIn.x * vIn.x * " << yLengthV << ");\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_XAmpV = m_Weight * m_XAmp; m_YAmpV = m_Weight * m_YAmp; m_XLengthV = 1 / max(SQR(m_XLength), T(1e-20)); m_YLengthV = 1 / max(SQR(m_YLength), T(1e-20)); } virtual void Random(QTIsaac& rand) { m_XAmp = 5 * (rand.Frand01() - T(0.5)); m_YAmp = 4 * (rand.Frand01() - T(0.5)); m_XLength = 2 * (rand.Frand01() + T(0.5)); m_YLength = 2 * (rand.Frand01() + T(0.5)); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_XAmp, prefix + "curve_xamp"));//Params. m_Params.push_back(ParamWithName(&m_YAmp, prefix + "curve_yamp")); m_Params.push_back(ParamWithName(&m_XLength, prefix + "curve_xlength", 1)); m_Params.push_back(ParamWithName(&m_YLength, prefix + "curve_ylength", 1)); m_Params.push_back(ParamWithName(true, &m_XAmpV, prefix + "curve_xampv"));//Precalc. m_Params.push_back(ParamWithName(true, &m_YAmpV, prefix + "curve_yampv")); m_Params.push_back(ParamWithName(true, &m_XLengthV, prefix + "curve_xlenv")); m_Params.push_back(ParamWithName(true, &m_YLengthV, prefix + "curve_ylenv")); } private: T m_XAmp;//Params. T m_YAmp; T m_XLength; T m_YLength; T m_XAmpV;//Precalc. T m_YAmpV; T m_XLengthV; T m_YLengthV; }; /// /// Edisc. /// template class EMBER_API EdiscVariation : public Variation { public: EdiscVariation(T weight = 1.0) : Variation("edisc", VAR_EDISC, weight, true) { } VARCOPY(EdiscVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tmp = helper.m_PrecalcSumSquares + 1; T tmp2 = 2 * helper.In.x; T r1 = sqrt(tmp + tmp2); T r2 = sqrt(tmp - tmp2); T xmax = (r1 + r2) * T(0.5); T a1 = log(xmax + sqrt(xmax - 1)); T a2 = -acos(Clamp(helper.In.x / xmax, -1, 1)); T w = m_Weight / T(11.57034632);//This is an interesting magic number. T snv, csv, snhu, cshu; sincos(a1, &snv, &csv); snhu = sinh(a2); cshu = cosh(a2); if (helper.In.y > 0.0) snv = -snv; helper.Out.x = w * cshu * csv; helper.Out.y = w * snhu * snv; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tmp = precalcSumSquares + 1.0;\n" << "\t\treal_t tmp2 = 2.0 * vIn.x;\n" << "\t\treal_t r1 = sqrt(tmp + tmp2);\n" << "\t\treal_t r2 = sqrt(tmp - tmp2);\n" << "\t\treal_t xmax = (r1 + r2) * 0.5;\n" << "\t\treal_t a1 = log(xmax + sqrt(xmax - 1.0));\n" << "\t\treal_t a2 = -acos(Clamp(vIn.x / xmax, -1.0, 1.0));\n" << "\t\treal_t w = xform->m_VariationWeights[" << varIndex << "] / 11.57034632;\n" << "\t\treal_t snv = sin(a1);\n" << "\t\treal_t csv = cos(a1);\n" << "\t\treal_t snhu = sinh(a2);\n" << "\t\treal_t cshu = cosh(a2);\n" << "\t\tif (vIn.y > 0)\n" << "\t\t snv = -snv;\n" << "\t\tvOut.x = w * cshu * csv;\n" << "\t\tvOut.y = w * snhu * snv;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Elliptic. /// template class EMBER_API EllipticVariation : public Variation { public: EllipticVariation(T weight = 1.0) : Variation("elliptic", VAR_ELLIPTIC, weight, true) { } VARCOPY(EllipticVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tmp = helper.m_PrecalcSumSquares + 1; T x2 = 2 * helper.In.x; T xmax = T(0.5) * (sqrt(tmp + x2) + sqrt(tmp - x2)); T a = helper.In.x / xmax; T b = 1 - a * a; T ssx = xmax - 1; T w = m_Weight / T(M_PI_2); if (b < 0) b = 0; else b = sqrt(b); if (ssx < 0) ssx = 0; else ssx = sqrt(ssx); helper.Out.x = w * atan2(a, b); if (helper.In.y > 0) helper.Out.y = w * log(xmax + ssx); else helper.Out.y = -(w * log(xmax + ssx)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tmp = precalcSumSquares + 1.0;\n" << "\t\treal_t x2 = 2.0 * vIn.x;\n" << "\t\treal_t xmax = 0.5 * (sqrt(tmp + x2) + sqrt(tmp - x2));\n" << "\t\treal_t a = vIn.x / xmax;\n" << "\t\treal_t b = 1.0 - a * a;\n" << "\t\treal_t ssx = xmax - 1.0;\n" << "\t\treal_t w = xform->m_VariationWeights[" << varIndex << "] / M_PI_2;\n" << "\n" << "\t\tif (b < 0)\n" << "\t\t b = 0;\n" << "\t\telse\n" << "\t\t b = sqrt(b);\n" << "\n" << "\t\tif (ssx < 0)\n" << "\t\t ssx = 0;\n" << "\t\telse\n" << "\t\t ssx = sqrt(ssx);\n" << "\n" << "\t\tvOut.x = w * atan2(a, b);\n" << "\n" << "\t\tif (vIn.y > 0)\n" << "\t\t vOut.y = w * log(xmax + ssx);\n" << "\t\telse\n" << "\t\t vOut.y = -(w * log(xmax + ssx));\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Escher. /// template class EMBER_API EscherVariation : public ParametricVariation { public: EscherVariation(T weight = 1.0) : ParametricVariation("escher", VAR_ESCHER, weight, true, false, false, false, true) { Init(); } PARVARCOPY(EscherVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a = helper.m_PrecalcAtanyx; T lnr = T(0.5) * log(helper.m_PrecalcSumSquares); T m = m_Weight * exp(m_C * lnr - m_D * a); T n = m_C * a + m_D * lnr; helper.Out.x = m * cos(n); helper.Out.y = m * sin(n); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string beta = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string d = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a = precalcAtanyx;\n" << "\t\treal_t lnr = 0.5 * log(precalcSumSquares);\n" << "\t\treal_t m = xform->m_VariationWeights[" << varIndex << "] * exp(" << c << " * lnr - " << d << " * a);\n" << "\t\treal_t n = " << c << " * a + " << d << " * lnr;\n" << "\n" << "\t\tvOut.x = m * cos(n);\n" << "\t\tvOut.y = m * sin(n);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { sincos(m_Beta, &m_D, &m_C); m_C = T(0.5) * (1 + m_C); m_D = T(0.5) * m_D; } virtual void Random(QTIsaac& rand) { SetParamVal("escher_beta", T(M_PI) * rand.Frand01()); } virtual bool SetParamVal(const char* name, T val) { if (!strcmp(name, "escher_beta")) { m_Beta = Fabsmod((val + T(M_PI)) / (2 * T(M_PI))) * 2 * T(M_PI) - T(M_PI); Precalc(); return true; } return ParametricVariation::SetParamVal(name, val); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Beta, prefix + "escher_beta"));//Params. m_Params.push_back(ParamWithName(true, &m_C, prefix + "escher_beta_c"));//Precalc. m_Params.push_back(ParamWithName(true, &m_D, prefix + "escher_beta_d")); } private: T m_Beta;//Params. T m_C;//Precalc. T m_D; }; /// /// Foci. /// template class EMBER_API FociVariation : public Variation { public: FociVariation(T weight = 1.0) : Variation("foci", VAR_FOCI, weight) { } VARCOPY(FociVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T expx = exp(helper.In.x) * T(0.5); T expnx = T(0.25) / expx; T sn, cn, tmp; sincos(helper.In.y, &sn, &cn); tmp = expx + expnx - cn; if (tmp == 0) tmp = EPS6; tmp = m_Weight / tmp; helper.Out.x = tmp * (expx - expnx); helper.Out.y = tmp * sn; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t expx = exp(vIn.x) * 0.5;\n" << "\t\treal_t expnx = 0.25 / expx;\n" << "\t\treal_t sn = sin(vIn.y);\n" << "\t\treal_t cn = cos(vIn.y);\n" << "\t\treal_t tmp = expx + expnx - cn;\n" << "\n" << "\t\tif (tmp == 0)\n" << "\t\t tmp = EPS6;\n" << "\n" << "\t\ttmp = xform->m_VariationWeights[" << varIndex << "] / tmp;\n" << "\n" << "\t\tvOut.x = tmp * (expx - expnx);\n" << "\t\tvOut.y = tmp * sn;\n" << "\t}\n"; return ss.str(); } }; /// /// LazySusan. /// template class EMBER_API LazySusanVariation : public ParametricVariation { public: LazySusanVariation(T weight = 1.0) : ParametricVariation("lazysusan", VAR_LAZYSUSAN, weight) { Init(); } PARVARCOPY(LazySusanVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T x = helper.In.x - m_X; T y = helper.In.y + m_Y; T r = sqrt(x * x + y * y); if (r < m_Weight) { T a = atan2(y, x) + m_Spin + m_Twist * (m_Weight - r); helper.Out.x = m_Weight * (r * cos(a) + m_X);//Fix to make it colapse to 0 when weight is 0.//SMOULDER helper.Out.y = m_Weight * (r * sin(a) - m_Y); } else { r = 1 + m_Space / (r + EPS6); helper.Out.x = m_Weight * (r * x + m_X);//Fix to make it colapse to 0 when weight is 0.//SMOULDER helper.Out.y = m_Weight * (r * y - m_Y); } helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string spin = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string space = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string twist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t x = vIn.x - " << x << ";\n" << "\t\treal_t y = vIn.y + " << y << ";\n" << "\t\treal_t r = sqrt(x * x + y * y);\n" << "\n" << "\t\tif (r < xform->m_VariationWeights[" << varIndex << "])\n" << "\t\t{\n" << "\t\t real_t a = atan2(y, x) + " << spin << " + " << twist << " * (xform->m_VariationWeights[" << varIndex << "] - r);\n" << "\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (r * cos(a) + " << x << ");\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (r * sin(a) - " << y << ");\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t r = 1.0 + " << space << " / (r + EPS6);\n" << "\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (r * x + " << x << ");\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (r * y - " << y << ");\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual bool SetParamVal(const char* name, T val) { if (!strcmp(name, "lazysusan_spin")) { m_Spin = Fabsmod(val / T(M_2PI)) * T(M_2PI); Precalc(); return true; } return ParametricVariation::SetParamVal(name, val); } virtual void Random(QTIsaac& rand) { m_X = 2 * rand.Frand11(); m_Y = 2 * rand.Frand11(); m_Spin = T(M_PI) * rand.Frand11(); m_Space = 2 * rand.Frand11(); m_Twist = 2 * rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Spin, prefix + "lazysusan_spin", T(M_PI))); m_Params.push_back(ParamWithName(&m_Space, prefix + "lazysusan_space")); m_Params.push_back(ParamWithName(&m_Twist, prefix + "lazysusan_twist")); m_Params.push_back(ParamWithName(&m_X, prefix + "lazysusan_x")); m_Params.push_back(ParamWithName(&m_Y, prefix + "lazysusan_y")); } private: T m_Spin; T m_Space; T m_Twist; T m_X; T m_Y; }; /// /// Loonie. /// template class EMBER_API LoonieVariation : public ParametricVariation { public: LoonieVariation(T weight = 1.0) : ParametricVariation("loonie", VAR_LOONIE, weight, true) { Init(); } PARVARCOPY(LoonieVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (helper.m_PrecalcSumSquares < m_W2) { T r = m_Weight * sqrt(m_W2 / helper.m_PrecalcSumSquares - 1); helper.Out.x = r * helper.In.x; helper.Out.y = r * helper.In.y; } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * helper.In.y; } helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string w2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tif (precalcSumSquares < " << w2 << ")\n" << "\t\t{\n" << "\t\t real_t r = xform->m_VariationWeights[" << varIndex << "] * sqrt(" << w2 << " / precalcSumSquares - 1.0);\n" << "\t\t vOut.x = r * vIn.x;\n" << "\t\t vOut.y = r * vIn.y;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_W2 = SQR(m_Weight); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_W2, prefix + "loonie_w2"));//Precalc. } private: T m_W2;//Precalc. }; /// /// Modulus. /// template class EMBER_API ModulusVariation : public ParametricVariation { public: ModulusVariation(T weight = 1.0) : ParametricVariation("modulus", VAR_MODULUS, weight) { Init(); } PARVARCOPY(ModulusVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (helper.In.x > m_X) helper.Out.x = m_Weight * (-m_X + fmod(helper.In.x + m_X, m_XRange)); else if (helper.In.x < -m_X) helper.Out.x = m_Weight * ( m_X - fmod(m_X - helper.In.x, m_XRange)); else helper.Out.x = m_Weight * helper.In.x; if (helper.In.y > m_Y) helper.Out.y = m_Weight * (-m_Y + fmod(helper.In.y + m_Y, m_YRange)); else if (helper.In.y < -m_Y) helper.Out.y = m_Weight * ( m_Y - fmod(m_Y - helper.In.y, m_YRange)); else helper.Out.y = m_Weight * helper.In.y; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int 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 xr = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yr = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tif (vIn.x > " << x << ")\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (-" << x << " + fmod(vIn.x + " << x << ", " << xr << "));\n" << "\t\telse if (vIn.x < -" << x << ")\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * ( " << x << " - fmod(" << x << " - vIn.x, " << xr << "));\n" << "\t\telse\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\n" << "\t\tif (vIn.y > " << y << ")\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (-" << y << " + fmod(vIn.y + " << y << ", " << yr << "));\n" << "\t\telse if (vIn.y < -" << y << ")\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * ( " << y << " - fmod(" << y << " - vIn.y, " << yr << "));\n" << "\t\telse\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_XRange = 2 * m_X; m_YRange = 2 * m_Y; } virtual void Random(QTIsaac& rand) { m_X = rand.Frand11(); m_Y = rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "modulus_x", 1));//Params. m_Params.push_back(ParamWithName(&m_Y, prefix + "modulus_y", 1)); m_Params.push_back(ParamWithName(true, &m_XRange, prefix + "modulus_xrange"));//Precalc. m_Params.push_back(ParamWithName(true, &m_YRange, prefix + "modulus_yrange")); } private: T m_X;//Params. T m_Y; T m_XRange;//Precalc. T m_YRange; }; /// /// Oscilloscope. /// template class EMBER_API OscilloscopeVariation : public ParametricVariation { public: OscilloscopeVariation(T weight = 1.0) : ParametricVariation("oscilloscope", VAR_OSCILLOSCOPE, weight) { Init(); } PARVARCOPY(OscilloscopeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T t; if (m_Damping == 0.0) t = m_Amplitude * cos(m_2PiFreq * helper.In.x) + m_Separation; else t = m_Amplitude * exp(-fabs(helper.In.x) * m_Damping) * cos(m_2PiFreq * helper.In.x) + m_Separation; if (fabs(helper.In.y) <= t) { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = -(m_Weight * helper.In.y); } else { helper.Out.x = m_Weight * helper.In.x; helper.Out.y = m_Weight * helper.In.y; } helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string separation = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string frequency = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string amplitude = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string damping = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string tpf = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t t;\n" << "\n" << "\t\tif (" << damping << " == 0.0)\n" << "\t\t t = " << amplitude << " * cos(" << tpf << " * vIn.x) + " << separation << ";\n" << "\t\telse\n" << "\t\t t = " << amplitude << " * exp(-fabs(vIn.x) * " << damping << ") * cos(" << tpf << " * vIn.x) + " << separation << ";\n" << "\n" << "\t\tif (fabs(vIn.y) <= t)\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 vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\t}\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_2PiFreq = m_Frequency * T(M_2PI); } virtual void Random(QTIsaac& rand) { m_Separation = 1 + rand.Frand11(); m_Frequency = T(M_PI) * rand.Frand11(); m_Amplitude = 1 + 2 * rand.Frand01(); m_Damping = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Separation, prefix + "oscilloscope_separation", 1));//Params. m_Params.push_back(ParamWithName(&m_Frequency, prefix + "oscilloscope_frequency", T(M_PI))); m_Params.push_back(ParamWithName(&m_Amplitude, prefix + "oscilloscope_amplitude", 1)); m_Params.push_back(ParamWithName(&m_Damping, prefix + "oscilloscope_damping")); m_Params.push_back(ParamWithName(true, &m_2PiFreq, prefix + "oscilloscope_2pifreq"));//Precalc. } private: T m_Separation;//Params. T m_Frequency; T m_Amplitude; T m_Damping; T m_2PiFreq;//Precalc. }; /// /// Polar2. /// template class EMBER_API Polar2Variation : public ParametricVariation { public: Polar2Variation(T weight = 1.0) : ParametricVariation("polar2", VAR_POLAR2, weight, true, false, false, true) { Init(); } PARVARCOPY(Polar2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Vvar * helper.m_PrecalcAtanxy; helper.Out.y = m_Vvar2 * log(helper.m_PrecalcSumSquares); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string vvar = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string vvar2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = " << vvar << " * precalcAtanxy;\n" << "\t\tvOut.y = " << vvar2 << " * log(precalcSumSquares);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Vvar = m_Weight / T(M_PI); m_Vvar2 = m_Vvar * T(0.5); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_Vvar, prefix + "polar2_vvar"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Vvar2, prefix + "polar2_vvar2")); } private: T m_Vvar; T m_Vvar2; }; /// /// Popcorn2. /// template class EMBER_API Popcorn2Variation : public ParametricVariation { public: Popcorn2Variation(T weight = 1.0) : ParametricVariation("popcorn2", VAR_POPCORN2, weight) { Init(); } PARVARCOPY(Popcorn2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * (helper.In.x + m_X * sin(tan(helper.In.y * m_C))); helper.Out.y = m_Weight * (helper.In.y + m_Y * sin(tan(helper.In.x * m_C))); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int 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 c = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + " << x << " * sin(tan(vIn.y * " << c << ")));\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + " << y << " * sin(tan(vIn.x * " << c << ")));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_X = T(0.2) + rand.Frand01(); m_Y = T(0.2) * rand.Frand01(); m_C = 5 * rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "popcorn2_x", T(0.1))); m_Params.push_back(ParamWithName(&m_Y, prefix + "popcorn2_y", T(0.1))); m_Params.push_back(ParamWithName(&m_C, prefix + "popcorn2_c", 3)); } private: T m_X; T m_Y; T m_C; }; /// /// Scry. /// Note that scry does not multiply by weight, but as the /// values still approach 0 as the weight approaches 0, it /// should be ok. /// template class EMBER_API ScryVariation : public ParametricVariation { public: ScryVariation(T weight = 1.0) : ParametricVariation("scry", VAR_SCRY, weight, true, true) { Init(); } PARVARCOPY(ScryVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T t = helper.m_PrecalcSumSquares; T r = 1 / (helper.m_PrecalcSqrtSumSquares * (t + m_InvWeight)); helper.Out.x = helper.In.x * r; helper.Out.y = helper.In.y * r; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string invWeight = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t t = precalcSumSquares;\n" << "\t\treal_t r = 1.0 / (precalcSqrtSumSquares * (t + " << invWeight << "));\n" << "\n" << "\t\tvOut.x = vIn.x * r;\n" << "\t\tvOut.y = vIn.y * r;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_InvWeight = 1 / (m_Weight + EPS6); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(true, &m_InvWeight, prefix + "scry_inv_weight"));//Precalcs only, no params. } private: T m_InvWeight;//Precalcs only, no params. }; /// /// Separation. /// template class EMBER_API SeparationVariation : public ParametricVariation { public: SeparationVariation(T weight = 1.0) : ParametricVariation("separation", VAR_SEPARATION, weight) { Init(); } PARVARCOPY(SeparationVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (helper.In.x > 0.0) helper.Out.x = m_Weight * (sqrt(SQR(helper.In.x) + m_XX) - helper.In.x * m_XInside); else helper.Out.x = -(m_Weight * (sqrt(SQR(helper.In.x) + m_XX) + helper.In.x * m_XInside)); if (helper.In.y > 0.0) helper.Out.y = m_Weight * (sqrt(SQR(helper.In.y) + m_YY) - helper.In.y * m_YInside); else helper.Out.y = -(m_Weight * (sqrt(SQR(helper.In.y) + m_YY) + helper.In.y * m_YInside)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xInside = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yInside = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tif (vIn.x > 0.0)\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * (sqrt(vIn.x * vIn.x + " << xx << ") - vIn.x * " << xInside << ");\n" << "\t\telse\n" << "\t\t vOut.x = -(xform->m_VariationWeights[" << varIndex << "] * (sqrt(vIn.x * vIn.x + " << xx << ") + vIn.x * " << xInside << "));\n" << "\n" << "\t\tif (vIn.y > 0.0)\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * (sqrt(vIn.y * vIn.y + " << yy << ") - vIn.y * " << yInside << ");\n" << "\t\telse\n" << "\t\t vOut.y = -(xform->m_VariationWeights[" << varIndex << "] * (sqrt(vIn.y * vIn.y + " << yy << ") + vIn.y * " << yInside << "));\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_XX = SQR(m_X); m_YY = SQR(m_Y); } virtual void Random(QTIsaac& rand) { m_X = 1 + rand.Frand11(); m_XInside = 1 + rand.Frand11(); m_Y = rand.Frand11(); m_YInside = rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "separation_x", 1));//Params. m_Params.push_back(ParamWithName(&m_XInside, prefix + "separation_xinside")); m_Params.push_back(ParamWithName(&m_Y, prefix + "separation_y", 1)); m_Params.push_back(ParamWithName(&m_YInside, prefix + "separation_yinside")); m_Params.push_back(ParamWithName(true, &m_XX, prefix + "separation_xx"));//Precalc. m_Params.push_back(ParamWithName(true, &m_YY, prefix + "separation_yy")); } private: T m_X;//Params. T m_XInside; T m_Y; T m_YInside; T m_XX;//Precalc. T m_YY; }; /// /// Split. /// template class EMBER_API SplitVariation : public ParametricVariation { public: SplitVariation(T weight = 1.0) : ParametricVariation("split", VAR_SPLIT, weight) { Init(); } PARVARCOPY(SplitVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { if (cos(helper.In.y * m_YAng) >= 0) helper.Out.x = m_Weight * helper.In.x; else helper.Out.x = -(m_Weight * helper.In.x); if (cos(helper.In.x * m_XAng) >= 0) helper.Out.y = m_Weight * helper.In.y; else helper.Out.y = -(m_Weight * helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string xSize = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string ySize = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string xAng = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string yAng = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tif (cos(vIn.y * " << yAng << ") >= 0)\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\telse\n" << "\t\t vOut.x = -(xform->m_VariationWeights[" << varIndex << "] * vIn.x);\n" << "\n" << "\t\tif (cos(vIn.x * " << xAng << ") >= 0)\n" << "\t\t vOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n" << "\t\telse\n" << "\t\t vOut.y = -(xform->m_VariationWeights[" << varIndex << "] * vIn.y);\n" << "\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_XAng = T(M_PI) * m_XSize; m_YAng = T(M_PI) * m_YSize; } virtual void Random(QTIsaac& rand) { m_XSize = rand.Frand11(); m_YSize = rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_XSize, prefix + "split_xsize", T(0.5)));//Params. m_Params.push_back(ParamWithName(&m_YSize, prefix + "split_ysize", T(0.5))); m_Params.push_back(ParamWithName(true, &m_XAng, prefix + "split_xang"));//Precalc. m_Params.push_back(ParamWithName(true, &m_YAng, prefix + "split_yang")); } private: T m_XSize;//Params. T m_YSize; T m_XAng;//Precalc. T m_YAng; }; /// /// Splits. /// template class EMBER_API SplitsVariation : public ParametricVariation { public: SplitsVariation(T weight = 1.0) : ParametricVariation("splits", VAR_SPLITS, weight) { Init(); } PARVARCOPY(SplitsVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { 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); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int 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\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\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_X = rand.Frand11(); m_Y = rand.Frand11(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_X, prefix + "splits_x")); m_Params.push_back(ParamWithName(&m_Y, prefix + "splits_y")); } private: T m_X; T m_Y; }; /// /// Stripes. /// template class EMBER_API StripesVariation : public ParametricVariation { public: StripesVariation(T weight = 1.0) : ParametricVariation("stripes", VAR_STRIPES, weight) { Init(); } PARVARCOPY(StripesVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T roundx = (T)Floor(helper.In.x + T(0.5)); T offsetx = helper.In.x - roundx; helper.Out.x = m_Weight * (offsetx * (1 - m_Space) + roundx); helper.Out.y = m_Weight * (helper.In.y + offsetx * offsetx * m_Warp); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string space = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string warp = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t roundx = floor(vIn.x + 0.5);\n" << "\t\treal_t offsetx = vIn.x - roundx;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (offsetx * (1.0 - " << space << ") + roundx);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + offsetx * offsetx * " << warp << ");\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Params[0].Set(rand.Frand01());//Space. m_Params[1].Set(5 * rand.Frand01());//Warp. } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Space, prefix + "stripes_space", T(0.5), REAL, T(0.5), 5)); m_Params.push_back(ParamWithName(&m_Warp, prefix + "stripes_warp")); } private: T m_Space; T m_Warp; }; /// /// Wedge. /// template class EMBER_API WedgeVariation : public ParametricVariation { public: WedgeVariation(T weight = 1.0) : ParametricVariation("wedge", VAR_WEDGE, weight, true, true, false, false, true) { Init(); } PARVARCOPY(WedgeVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSqrtSumSquares; T a = helper.m_PrecalcAtanyx + m_Swirl * r; T c = (T)Floor((m_Count * a + T(M_PI)) * T(M_1_PI) * T(0.5)); a = a * m_CompFac + c * m_Angle; r = m_Weight * (r + m_Hole); helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string count = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string swirl = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string compFac = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r = precalcSqrtSumSquares;\n" << "\t\treal_t a = precalcAtanyx + " << swirl << " * r;\n" << "\t\treal_t c = floor((" << count << " * a + M_PI) * M_1_PI * 0.5);\n" << "\n" << "\t\ta = a * " << compFac << " + c * " << angle << ";\n" << "\t\tr = xform->m_VariationWeights[" << varIndex << "] * (r + " << hole << ");\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_CompFac = 1 - m_Angle * m_Count * T(M_1_PI) * T(0.5); } virtual void Random(QTIsaac& rand) { m_Angle = T(M_PI) * rand.Frand01(); m_Hole = T(0.5) * rand.Frand11(); m_Count = (T)Floor(5 * rand.Frand01()) + 1; m_Swirl = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "wedge_angle", T(M_PI_2)));//Params. m_Params.push_back(ParamWithName(&m_Hole, prefix + "wedge_hole")); m_Params.push_back(ParamWithName(&m_Count, prefix + "wedge_count", 2, INTEGER, 1)); m_Params.push_back(ParamWithName(&m_Swirl, prefix + "wedge_swirl")); m_Params.push_back(ParamWithName(true, &m_CompFac, prefix + "wedge_compfac"));//Precalc. } private: T m_Angle;//Params. T m_Hole; T m_Count; T m_Swirl; T m_CompFac;//Precalc. }; /// /// Wedge julia. /// template class EMBER_API WedgeJuliaVariation : public ParametricVariation { public: WedgeJuliaVariation(T weight = 1.0) : ParametricVariation("wedge_julia", VAR_WEDGE_JULIA, weight, true, false, false, false, true) { Init(); } PARVARCOPY(WedgeJuliaVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn); int tRand = (int)(m_Rn * rand.Frand01()); T a = (helper.m_PrecalcAtanyx + M_2PI * tRand) / m_Power; T c = (T)Floor((m_Count * a + T(M_PI)) * T(M_1_PI) * T(0.5)); a = a * m_Cf + c * m_Angle; helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params. string count = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc. string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string cf = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << ");\n" << "\t\tint tRand = (int)(" << rn << " * MwcNext01(mwc));\n" << "\t\treal_t a = (precalcAtanyx + M_2PI * tRand) / " << power << ";\n" << "\t\treal_t c = floor((" << count << " * a + M_PI) * M_1_PI * 0.5);\n" << "\n" << "\t\ta = a * " << cf << " + c * " << angle << ";\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Cf = 1 - m_Angle * m_Count * T(M_1_PI) * T(0.5); m_Rn = fabs(m_Power); m_Cn = m_Dist / m_Power / 2; } virtual void Random(QTIsaac& rand) { m_Power = (T)(int)(5 * rand.Frand01() + 2); m_Dist = 1; m_Count = (T)(int)(3 * rand.Frand01() + 1); m_Angle = T(M_PI) * rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "wedge_julia_angle"));//Params. m_Params.push_back(ParamWithName(&m_Count, prefix + "wedge_julia_count", 1)); m_Params.push_back(ParamWithName(&m_Power, prefix + "wedge_julia_power", 1)); m_Params.push_back(ParamWithName(&m_Dist, prefix + "wedge_julia_dist")); m_Params.push_back(ParamWithName(true, &m_Rn, prefix + "wedge_julia_rn"));//Precalc. m_Params.push_back(ParamWithName(true, &m_Cn, prefix + "wedge_julia_cn")); m_Params.push_back(ParamWithName(true, &m_Cf, prefix + "wedge_julia_cf")); } private: T m_Angle;//Params. T m_Count; T m_Power; T m_Dist; T m_Rn;//Precalc. T m_Cn; T m_Cf; }; /// /// Wedge sph. /// template class EMBER_API WedgeSphVariation : public ParametricVariation { public: WedgeSphVariation(T weight = 1.0) : ParametricVariation("wedge_sph", VAR_WEDGE_SPH, weight, true, true, false, false, true) { Init(); } PARVARCOPY(WedgeSphVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = 1 / (helper.m_PrecalcSqrtSumSquares + T(EPS)); T a = helper.m_PrecalcAtanyx + m_Swirl * r; T c = (T)Floor((m_Count * a + T(M_PI)) * T(M_1_PI) * T(0.5)); T compFac = 1 - m_Angle * m_Count * T(M_1_PI) * T(0.5); a = a * compFac + c * m_Angle; r = m_Weight * (r + m_Hole); helper.Out.x = r * cos(a); helper.Out.y = r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string count = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string hole = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string swirl = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t r = 1.0 / (precalcSqrtSumSquares + EPS);\n" << "\t\treal_t a = precalcAtanyx + " << swirl << " * r;\n" << "\t\treal_t c = floor((" << count << " * a + M_PI) * M_1_PI * 0.5);\n" << "\t\treal_t compFac = 1 - " << angle << " * " << count << " * M_1_PI * 0.5;\n" << "\n" << "\t\ta = a * compFac + c * " << angle << ";\n" << "\t\tr = xform->m_VariationWeights[" << varIndex << "] * (r + " << hole << ");\n" << "\t\tvOut.x = r * cos(a);\n" << "\t\tvOut.y = r * sin(a);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Angle = T(M_PI) * rand.Frand01(); m_Count = (T)Floor(5 * rand.Frand01()) + 1; m_Hole = T(0.5) * rand.Frand11(); m_Swirl = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Angle, prefix + "wedge_sph_angle")); m_Params.push_back(ParamWithName(&m_Count, prefix + "wedge_sph_hole", 1)); m_Params.push_back(ParamWithName(&m_Hole, prefix + "wedge_sph_count")); m_Params.push_back(ParamWithName(&m_Swirl, prefix + "wedge_sph_swirl")); } private: T m_Angle; T m_Count; T m_Hole; T m_Swirl; }; /// /// Whorl. /// template class EMBER_API WhorlVariation : public ParametricVariation { public: WhorlVariation(T weight = 1.0) : ParametricVariation("whorl", VAR_WHORL, weight, true, true, false, false, true) { Init(); } PARVARCOPY(WhorlVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T a, r = helper.m_PrecalcSqrtSumSquares; if (r < m_Weight) a = helper.m_PrecalcAtanyx + m_Inside / (m_Weight - r); else a = helper.m_PrecalcAtanyx + m_Outside / (m_Weight - r); helper.Out.x = m_Weight * r * cos(a); helper.Out.y = m_Weight * r * sin(a); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string inside = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string outside = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t a;\n" << "\t\treal_t r = precalcSqrtSumSquares;\n" << "\n" << "\t\tif (r < xform->m_VariationWeights[" << varIndex << "])\n" << "\t\t a = precalcAtanyx + " << inside << " / (xform->m_VariationWeights[" << varIndex << "] - r);\n" << "\t\telse\n" << "\t\t a = precalcAtanyx + " << outside << " / (xform->m_VariationWeights[" << varIndex << "] - r);\n" << "\n" << "\t\tvOut.x = (xform->m_VariationWeights[" << varIndex << "] * r * cos(a));\n" << "\t\tvOut.y = (xform->m_VariationWeights[" << varIndex << "] * r * sin(a));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Inside = rand.Frand01(); m_Outside = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Inside, prefix + "whorl_inside", 1)); m_Params.push_back(ParamWithName(&m_Outside, prefix + "whorl_outside", 1)); } private: T m_Inside; T m_Outside; }; /// /// Waves. /// template class EMBER_API Waves2Variation : public ParametricVariation { public: Waves2Variation(T weight = 1.0) : ParametricVariation("waves2", VAR_WAVES2, weight, true, true) { Init(); } PARVARCOPY(Waves2Variation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * (helper.In.x + m_ScaleX * sin(helper.In.y * m_FreqX)); helper.Out.y = m_Weight * (helper.In.y + m_ScaleY * sin(helper.In.x * m_FreqY)); helper.Out.z = m_Weight * (helper.In.z + m_ScaleZ * sin(helper.m_PrecalcSqrtSumSquares * m_FreqZ)); } virtual string OpenCLString() { ostringstream ss, ss2; int 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 freqZ = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scaleZ = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + " << scaleX << " * sin(vIn.y * " << freqX << "));\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (vIn.y + " << scaleY << " * sin(vIn.x * " << freqY << "));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * (vIn.z + " << scaleZ << " * sin(precalcSqrtSumSquares * " << freqZ << "));\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_FreqX = 4 * rand.Frand01(); m_ScaleX = T(0.5) + rand.Frand01(); m_FreqY = 4 * rand.Frand01(); m_ScaleY = T(0.5) + rand.Frand01(); m_FreqZ = 0; m_ScaleZ = 0; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_FreqX, prefix + "waves2_freqx", 2)); m_Params.push_back(ParamWithName(&m_ScaleX, prefix + "waves2_scalex")); m_Params.push_back(ParamWithName(&m_FreqY, prefix + "waves2_freqy", 2)); m_Params.push_back(ParamWithName(&m_ScaleY, prefix + "waves2_scaley")); m_Params.push_back(ParamWithName(&m_FreqZ, prefix + "waves2_freqz")); m_Params.push_back(ParamWithName(&m_ScaleZ, prefix + "waves2_scalez")); } private: T m_FreqX; T m_ScaleX; T m_FreqY; T m_ScaleY; T m_FreqZ; T m_ScaleZ; }; /// /// Exp. /// template class EMBER_API ExpVariation : public Variation { public: ExpVariation(T weight = 1.0) : Variation("exp", VAR_EXP, weight) { } VARCOPY(ExpVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T expe = m_Weight * exp(helper.In.x); helper.Out.x = expe * cos(helper.In.y); helper.Out.y = expe * sin(helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t expe = xform->m_VariationWeights[" << varIndex << "] * exp(vIn.x);\n" << "\n" << "\t\tvOut.x = expe * cos(vIn.y);\n" << "\t\tvOut.y = expe * sin(vIn.y);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Log. /// template class EMBER_API LogVariation : public ParametricVariation { public: LogVariation(T weight = 1.0) : ParametricVariation("log", VAR_LOG, weight, true, false, false, false, true) { Init(); } PARVARCOPY(LogVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * log(helper.m_PrecalcSumSquares) * m_Denom; helper.Out.y = m_Weight * helper.m_PrecalcAtanyx; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string base = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string denom = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * log(precalcSumSquares) * " << denom << ";\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * precalcAtanyx;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Denom = T(0.5) / log(m_Base); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Base, prefix + "log_base", T(M_E), REAL, EPS6, TMAX)); m_Params.push_back(ParamWithName(true, &m_Denom, prefix + "log_denom"));//Precalc. } private: T m_Base; T m_Denom;//Precalc. }; /// /// Sine. /// template class EMBER_API SinVariation : public Variation { public: SinVariation(T weight = 1.0) : Variation("sin", VAR_SIN, weight) { } VARCOPY(SinVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { helper.Out.x = m_Weight * sin(helper.In.x) * cosh(helper.In.y); helper.Out.y = m_Weight * cos(helper.In.x) * sinh(helper.In.y); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sin(vIn.x) * cosh(vIn.y);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * cos(vIn.x) * sinh(vIn.y);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cosine. /// template class EMBER_API CosVariation : public Variation { public: CosVariation(T weight = 1.0) : Variation("cos", VAR_COS, weight) { } VARCOPY(CosVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { //clamp fabs x and y to 7.104760e+002 for cosh, and |x| 7.104760e+002 for sinh helper.Out.x = m_Weight * cos(helper.In.x) * cosh(helper.In.y); helper.Out.y = -(m_Weight * sin(helper.In.x) * sinh(helper.In.y)); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cos(vIn.x) * cosh(vIn.y);\n" << "\t\tvOut.y = -(xform->m_VariationWeights[" << varIndex << "] * sin(vIn.x) * sinh(vIn.y));\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Tangent. /// template class EMBER_API TanVariation : public Variation { public: TanVariation(T weight = 1.0) : Variation("tan", VAR_TAN, weight) { } VARCOPY(TanVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tansin, tancos, tansinh, tancosh, tanden; sincos(2 * helper.In.x, &tansin, &tancos); tansinh = sinh(2 * helper.In.y); tancosh = cosh(2 * helper.In.y); tanden = 1 / (tancos + tancosh); helper.Out.x = m_Weight * tanden * tansin; helper.Out.y = m_Weight * tanden * tansinh; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tansin = sin(2.0 * vIn.x);\n" << "\t\treal_t tancos = cos(2.0 * vIn.x);\n" << "\t\treal_t tansinh = sinh(2.0 * vIn.y);\n" << "\t\treal_t tancosh = cosh(2.0 * vIn.y);\n" << "\t\treal_t tanden = 1.0 / (tancos + tancosh);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * tanden * tansin;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * tanden * tansinh;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Sec. /// template class EMBER_API SecVariation : public Variation { public: SecVariation(T weight = 1.0) : Variation("sec", VAR_SEC, weight) { } VARCOPY(SecVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T secsin, seccos, secsinh, seccosh, secden; sincos(helper.In.x, &secsin, &seccos); secsinh = sinh(helper.In.y); seccosh = cosh(helper.In.y); secden = 2 / (cos(2 * helper.In.x) + cosh(2 * helper.In.y)); helper.Out.x = m_Weight * secden * seccos * seccosh; helper.Out.y = m_Weight * secden * secsin * secsinh; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t secsin = sin(vIn.x);\n" << "\t\treal_t seccos = cos(vIn.x);\n" << "\t\treal_t secsinh = sinh(vIn.y);\n" << "\t\treal_t seccosh = cosh(vIn.y);\n" << "\t\treal_t secden = 2.0 / (cos(2.0 * vIn.x) + cosh(2.0 * vIn.y));\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * secden * seccos * seccosh;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * secden * secsin * secsinh;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cosecant. /// template class EMBER_API CscVariation : public Variation { public: CscVariation(T weight = 1.0) : Variation("csc", VAR_CSC, weight) { } VARCOPY(CscVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T cscsin, csccos, cscsinh, csccosh, cscden; sincos(helper.In.x, &cscsin, &csccos); cscsinh = sinh(helper.In.y); csccosh = cosh(helper.In.y); cscden = 2 / (cosh(2 * helper.In.y) - cos(2 * helper.In.x)); helper.Out.x = m_Weight * cscden * cscsin * csccosh; helper.Out.y = -(m_Weight * cscden * csccos * cscsinh); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t cscsin = sin(vIn.x);\n" << "\t\treal_t csccos = cos(vIn.x);\n" << "\t\treal_t cscsinh = sinh(vIn.y);\n" << "\t\treal_t csccosh = cosh(vIn.y);\n" << "\t\treal_t cscden = 2.0 / (cosh(2.0 * vIn.y) - cos(2.0 * vIn.x));\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cscden * cscsin * csccosh;\n" << "\t\tvOut.y = -(xform->m_VariationWeights[" << varIndex << "] * cscden * csccos * cscsinh);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cotangent. /// template class EMBER_API CotVariation : public Variation { public: CotVariation(T weight = 1.0) : Variation("cot", VAR_COT, weight) { } VARCOPY(CotVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T cotsin, cotcos, cotsinh, cotcosh, cotden; sincos(2 * helper.In.x, &cotsin, &cotcos); cotsinh = sinh(2 * helper.In.y); cotcosh = cosh(2 * helper.In.y); cotden = 1 / (cotcosh - cotcos); helper.Out.x = m_Weight * cotden * cotsin; helper.Out.y = m_Weight * cotden * -1 * cotsinh; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t cotsin = sin(2.0 * vIn.x);\n" << "\t\treal_t cotcos = cos(2.0 * vIn.x);\n" << "\t\treal_t cotsinh = sinh(2.0 * vIn.y);\n" << "\t\treal_t cotcosh = cosh(2.0 * vIn.y);\n" << "\t\treal_t cotden = 1.0 / (cotcosh - cotcos);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cotden * cotsin;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * cotden * -1 * cotsinh;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Sinh. /// template class EMBER_API SinhVariation : public Variation { public: SinhVariation(T weight = 1.0) : Variation("sinh", VAR_SINH, weight) { } VARCOPY(SinhVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T sinhsin, sinhcos, sinhsinh, sinhcosh; sincos(helper.In.y, &sinhsin, &sinhcos); sinhsinh = sinh(helper.In.x); sinhcosh = cosh(helper.In.x); helper.Out.x = m_Weight * sinhsinh * sinhcos; helper.Out.y = m_Weight * sinhcosh * sinhsin; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t sinhsin = sin(vIn.y);\n" << "\t\treal_t sinhcos = cos(vIn.y);\n" << "\t\treal_t sinhsinh = sinh(vIn.x);\n" << "\t\treal_t sinhcosh = cosh(vIn.x);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sinhsinh * sinhcos;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * sinhcosh * sinhsin;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Cosh. /// template class EMBER_API CoshVariation : public Variation { public: CoshVariation(T weight = 1.0) : Variation("cosh", VAR_COSH, weight) { } VARCOPY(CoshVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T coshsin,coshcos,coshsinh,coshcosh; sincos(helper.In.y, &coshsin, &coshcos); coshsinh = sinh(helper.In.x); coshcosh = cosh(helper.In.x); helper.Out.x = m_Weight * coshcosh * coshcos; helper.Out.y = m_Weight * coshsinh * coshsin; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t coshsin = sin(vIn.y);\n" << "\t\treal_t coshcos = cos(vIn.y);\n" << "\t\treal_t coshsinh = sinh(vIn.x);\n" << "\t\treal_t coshcosh = cosh(vIn.x);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * coshcosh * coshcos;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * coshsinh * coshsin;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Tanh. /// template class EMBER_API TanhVariation : public Variation { public: TanhVariation(T weight = 1.0) : Variation("tanh", VAR_TANH, weight) { } VARCOPY(TanhVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T tanhsin, tanhcos, tanhsinh, tanhcosh, tanhden; sincos(2 * helper.In.y, &tanhsin, &tanhcos); tanhsinh = sinh(2 * helper.In.x); tanhcosh = cosh(2 * helper.In.x); tanhden = 1 / (tanhcos + tanhcosh); helper.Out.x = m_Weight * tanhden * tanhsinh; helper.Out.y = m_Weight * tanhden * tanhsin; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t tanhsin = sin(2.0 * vIn.y);\n" << "\t\treal_t tanhcos = cos(2.0 * vIn.y);\n" << "\t\treal_t tanhsinh = sinh(2.0 * vIn.x);\n" << "\t\treal_t tanhcosh = cosh(2.0 * vIn.x);\n" << "\t\treal_t tanhden = 1.0 / (tanhcos + tanhcosh);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * tanhden * tanhsinh;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * tanhden * tanhsin;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Sech /// template class EMBER_API SechVariation : public Variation { public: SechVariation(T weight = 1.0) : Variation("sech", VAR_SECH, weight) { } VARCOPY(SechVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T sechsin, sechcos, sechsinh, sechcosh, sechden; sincos(helper.In.y, &sechsin, &sechcos); sechsinh = sinh(helper.In.x); sechcosh = cosh(helper.In.x); sechden = 2 / (cos(2 * helper.In.y) + cosh(2 * helper.In.x)); helper.Out.x = m_Weight * sechden * sechcos * sechcosh; helper.Out.y = -(m_Weight * sechden * sechsin * sechsinh); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t sechsin = sin(vIn.y);\n" << "\t\treal_t sechcos = cos(vIn.y);\n" << "\t\treal_t sechsinh = sinh(vIn.x);\n" << "\t\treal_t sechcosh = cosh(vIn.x);\n" << "\t\treal_t sechden = 2.0 / (cos(2.0 * vIn.y) + cosh(2.0 * vIn.x));\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * sechden * sechcos * sechcosh;\n" << "\t\tvOut.y = -(xform->m_VariationWeights[" << varIndex << "] * sechden * sechsin * sechsinh);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Csch. /// template class EMBER_API CschVariation : public Variation { public: CschVariation(T weight = 1.0) : Variation("csch", VAR_CSCH, weight) { } VARCOPY(CschVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T cschsin, cschcos, cschsinh, cschcosh, cschden; sincos(helper.In.y, &cschsin, &cschcos); cschsinh = sinh(helper.In.x); cschcosh = cosh(helper.In.x); cschden = 2 / (cosh(2 * helper.In.x) - cos(2 * helper.In.y)); helper.Out.x = m_Weight * cschden * cschsinh * cschcos; helper.Out.y = -(m_Weight * cschden * cschcosh * cschsin); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t cschsin = sin(vIn.y);\n" << "\t\treal_t cschcos = cos(vIn.y);\n" << "\t\treal_t cschsinh = sinh(vIn.x);\n" << "\t\treal_t cschcosh = cosh(vIn.x);\n" << "\t\treal_t cschden = 2.0 / (cosh(2.0 * vIn.x) - cos(2.0 * vIn.y));\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cschden * cschsinh * cschcos;\n" << "\t\tvOut.y = -(xform->m_VariationWeights[" << varIndex << "] * cschden * cschcosh * cschsin);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Coth. /// template class EMBER_API CothVariation : public Variation { public: CothVariation(T weight = 1.0) : Variation("coth", VAR_COTH, weight) { } VARCOPY(CothVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T cothsin, cothcos, cothsinh, cothcosh, cothden; sincos(2 * helper.In.y, &cothsin, &cothcos); cothsinh = sinh(2 * helper.In.x); cothcosh = cosh(2 * helper.In.x); cothden = 1 / (cothcosh - cothcos); helper.Out.x = m_Weight * cothden * cothsinh; helper.Out.y = m_Weight * cothden * cothsin; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss; int i = 0, varIndex = IndexInXform(); ss << "\t{\n" << "\t\treal_t cothsin = sin(2.0 * vIn.y);\n" << "\t\treal_t cothcos = cos(2.0 * vIn.y);\n" << "\t\treal_t cothsinh = sinh(2.0 * vIn.x);\n" << "\t\treal_t cothcosh = cosh(2.0 * vIn.x);\n" << "\t\treal_t cothden = 1.0 / (cothcosh - cothcos);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * cothden * cothsinh;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * cothden * cothsin;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } }; /// /// Auger. /// template class EMBER_API AugerVariation : public ParametricVariation { public: AugerVariation(T weight = 1.0) : ParametricVariation("auger", VAR_AUGER, weight) { Init(); } PARVARCOPY(AugerVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T s = sin(m_Freq * helper.In.x); T t = sin(m_Freq * helper.In.y); T dy = helper.In.y + m_AugerWeight * (m_Scale * s / 2 + fabs(helper.In.y) * s); T dx = helper.In.x + m_AugerWeight * (m_Scale * t / 2 + fabs(helper.In.x) * t); helper.Out.x = m_Weight * (helper.In.x + m_Symmetry * (dx - helper.In.x)); helper.Out.y = m_Weight * dy; helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string symmetry = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string augerWeight = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string freq = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t s = sin(" << freq << " * vIn.x);\n" << "\t\treal_t t = sin(" << freq << " * vIn.y);\n" << "\t\treal_t dy = vIn.y + " << augerWeight << " * (" << scale << " * s / 2.0 + fabs(vIn.y) * s);\n" << "\t\treal_t dx = vIn.x + " << augerWeight << " * (" << scale << " * t / 2.0 + fabs(vIn.x) * t);\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + " << symmetry << " * (dx - vIn.x));\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * dy;\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Random(QTIsaac& rand) { m_Symmetry = 0; m_AugerWeight = T(0.5) + rand.Frand01() / 2; m_Freq = (T)Floor(5 * rand.Frand01()) + 1; m_Scale = rand.Frand01(); } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Symmetry, prefix + "auger_sym")); m_Params.push_back(ParamWithName(&m_AugerWeight, prefix + "auger_weight", T(0.5))); m_Params.push_back(ParamWithName(&m_Freq, prefix + "auger_freq", 5)); m_Params.push_back(ParamWithName(&m_Scale, prefix + "auger_scale", T(0.1))); } private: T m_Symmetry; T m_AugerWeight; T m_Freq; T m_Scale; }; /// /// Flux. /// template class EMBER_API FluxVariation : public ParametricVariation { public: FluxVariation(T weight = 1.0) : ParametricVariation("flux", VAR_FLUX, weight) { Init(); } PARVARCOPY(FluxVariation) void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T xpw = helper.In.x + m_Weight; T xmw = helper.In.x - m_Weight; T yy = SQR(helper.In.y); T frac = sqrt(yy + SQR(xmw)); if (frac == 0) frac = 1; T avgr = m_Weight * (m_Spr * sqrt(sqrt(yy + SQR(xpw)) / frac)); T avga = (atan2(helper.In.y, xmw) - atan2(helper.In.y, xpw)) * T(0.5); helper.Out.x = avgr * cos(avga); helper.Out.y = avgr * sin(avga); helper.Out.z = m_Weight * helper.In.z; } virtual string OpenCLString() { ostringstream ss, ss2; int i = 0, varIndex = IndexInXform(); ss2 << "_" << XformIndexInEmber() << "]"; string index = ss2.str(); string spread = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string spr = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\treal_t xpw = vIn.x + xform->m_VariationWeights[" << varIndex << "];\n" << "\t\treal_t xmw = vIn.x - xform->m_VariationWeights[" << varIndex << "];\n" << "\t\treal_t yy = SQR(vIn.y);\n" << "\t\treal_t frac = sqrt(yy + SQR(xmw));\n" << "\n" << "\t\tif (frac == 0.0)\n" << "\t\t frac = 1.0;\n" << "\n" << "\t\treal_t avgr = xform->m_VariationWeights[" << varIndex << "] * (" << spr << " * sqrt(sqrt(yy + SQR(xpw)) / frac));\n" << "\t\treal_t avga = (atan2(vIn.y, xmw) - atan2(vIn.y, xpw)) * 0.5;\n" << "\n" << "\t\tvOut.x = avgr * cos(avga);\n" << "\t\tvOut.y = avgr * sin(avga);\n" << "\t\tvOut.z = xform->m_VariationWeights[" << varIndex << "] * vIn.z;\n" << "\t}\n"; return ss.str(); } virtual void Precalc() { m_Spr = 2 + m_Spread; } virtual void Random(QTIsaac& rand) { m_Spread = T(0.5) + rand.Frand01() / 2; } protected: void Init() { string prefix = Prefix(); m_Params.clear(); m_Params.push_back(ParamWithName(&m_Spread, prefix + "flux_spread"));//Params. m_Params.push_back(ParamWithName(true, &m_Spr, prefix + "flux_spr"));//Precalc. } private: T m_Spread;//Params. T m_Spr;//Precalc. }; MAKEPREPOSTVAR(Linear, linear, LINEAR) MAKEPREPOSTVAR(Sinusoidal, sinusoidal, SINUSOIDAL) MAKEPREPOSTVAR(Spherical, spherical, SPHERICAL) MAKEPREPOSTVAR(Swirl, swirl, SWIRL) MAKEPREPOSTVAR(Horseshoe, horseshoe, HORSESHOE) MAKEPREPOSTVAR(Polar, polar, POLAR) MAKEPREPOSTVAR(Handkerchief, handkerchief, HANDKERCHIEF) MAKEPREPOSTVAR(Heart, heart, HEART) MAKEPREPOSTPARVAR(Disc, disc, DISC) MAKEPREPOSTVAR(Spiral, spiral, SPIRAL) MAKEPREPOSTVAR(Hyperbolic, hyperbolic, HYPERBOLIC) MAKEPREPOSTVAR(Diamond, diamond, DIAMOND) MAKEPREPOSTVAR(Ex, ex, EX) MAKEPREPOSTVAR(Julia, julia, JULIA) MAKEPREPOSTVAR(Bent, bent, BENT) MAKEPREPOSTPARVAR(Waves, waves, WAVES) MAKEPREPOSTVAR(Fisheye, fisheye, FISHEYE) MAKEPREPOSTVAR(Popcorn, popcorn, POPCORN) MAKEPREPOSTVAR(Exponential, exponential, EXPONENTIAL) MAKEPREPOSTVAR(Power, power, POWER) MAKEPREPOSTVAR(Cosine, cosine, COSINE) MAKEPREPOSTVAR(Rings, rings, RINGS) MAKEPREPOSTVAR(Fan, fan, FAN) MAKEPREPOSTPARVAR(Blob, blob, BLOB) MAKEPREPOSTPARVAR(Pdj, pdj, PDJ) MAKEPREPOSTPARVAR(Fan2, fan2, FAN2) MAKEPREPOSTPARVAR(Rings2, rings2, RINGS2) MAKEPREPOSTVAR(Eyefish, eyefish, EYEFISH) MAKEPREPOSTVAR(Bubble, bubble, BUBBLE) MAKEPREPOSTVAR(Cylinder, cylinder, CYLINDER) MAKEPREPOSTPARVAR(Perspective, perspective, PERSPECTIVE) MAKEPREPOSTVAR(Noise, noise, NOISE) MAKEPREPOSTPARVAR(JuliaNGeneric, julian, JULIAN) MAKEPREPOSTPARVAR(JuliaScope, juliascope, JULIASCOPE) MAKEPREPOSTVARASSIGN(Blur, blur, BLUR, ASSIGNTYPE_SUM) MAKEPREPOSTVARASSIGN(GaussianBlur, gaussian_blur, GAUSSIAN_BLUR, ASSIGNTYPE_SUM) MAKEPREPOSTPARVAR(RadialBlur, radial_blur, RADIAL_BLUR) MAKEPREPOSTPARVARASSIGN(Pie, pie, PIE, ASSIGNTYPE_SUM) MAKEPREPOSTPARVAR(Ngon, ngon, NGON) MAKEPREPOSTPARVAR(Curl, curl, CURL) MAKEPREPOSTPARVAR(Rectangles, rectangles, RECTANGLES) MAKEPREPOSTVARASSIGN(Arch, arch, ARCH, ASSIGNTYPE_SUM) MAKEPREPOSTVAR(Tangent, tangent, TANGENT) MAKEPREPOSTVARASSIGN(Square, square, SQUARE, ASSIGNTYPE_SUM) MAKEPREPOSTVAR(Rays, rays, RAYS) MAKEPREPOSTVAR(Blade, blade, BLADE) MAKEPREPOSTVAR(Secant2, secant2, SECANT2) MAKEPREPOSTVAR(TwinTrian, TwinTrian, TWINTRIAN) MAKEPREPOSTVAR(Cross, cross, CROSS) MAKEPREPOSTPARVAR(Disc2, disc2, DISC2) MAKEPREPOSTPARVAR(SuperShape, super_shape, SUPER_SHAPE) MAKEPREPOSTPARVAR(Flower, flower, FLOWER) MAKEPREPOSTPARVAR(Conic, conic, CONIC) MAKEPREPOSTPARVAR(Parabola, parabola, PARABOLA) MAKEPREPOSTPARVAR(Bent2, bent2, BENT2) MAKEPREPOSTPARVAR(Bipolar, bipolar, BIPOLAR) MAKEPREPOSTVAR(Boarders, boarders, BOARDERS) MAKEPREPOSTVAR(Butterfly, butterfly, BUTTERFLY) MAKEPREPOSTPARVAR(Cell, cell, CELL) MAKEPREPOSTPARVAR(Cpow, cpow, CPOW) MAKEPREPOSTPARVAR(Curve, curve, CURVE) MAKEPREPOSTVAR(Edisc, edisc, EDISC) MAKEPREPOSTVAR(Elliptic, elliptic, ELLIPTIC) MAKEPREPOSTPARVAR(Escher, escher, ESCHER) MAKEPREPOSTVAR(Foci, foci, FOCI) MAKEPREPOSTPARVAR(LazySusan, lazysusan, LAZYSUSAN) MAKEPREPOSTPARVAR(Loonie, loonie, LOONIE) MAKEPREPOSTPARVAR(Modulus, modulus, MODULUS) MAKEPREPOSTPARVAR(Oscilloscope, oscilloscope, OSCILLOSCOPE) MAKEPREPOSTPARVAR(Polar2, polar2, POLAR2) MAKEPREPOSTPARVAR(Popcorn2, popcorn2, POPCORN2) MAKEPREPOSTPARVAR(Scry, scry, SCRY) MAKEPREPOSTPARVAR(Separation, separation, SEPARATION) MAKEPREPOSTPARVAR(Split, split, SPLIT) MAKEPREPOSTPARVAR(Splits, splits, SPLITS) MAKEPREPOSTPARVAR(Stripes, stripes, STRIPES) MAKEPREPOSTPARVAR(Wedge, wedge, WEDGE) MAKEPREPOSTPARVAR(WedgeJulia, wedge_julia, WEDGE_JULIA) MAKEPREPOSTPARVAR(WedgeSph, wedge_sph, WEDGE_SPH) MAKEPREPOSTPARVAR(Whorl, whorl, WHORL) MAKEPREPOSTPARVAR(Waves2, waves2, WAVES2) MAKEPREPOSTVAR(Exp, exp, EXP) MAKEPREPOSTPARVAR(Log, log, LOG) MAKEPREPOSTVAR(Sin, sin, SIN) MAKEPREPOSTVAR(Cos, cos, COS) MAKEPREPOSTVAR(Tan, tan, TAN) MAKEPREPOSTVAR(Sec, sec, SEC) MAKEPREPOSTVAR(Csc, csc, CSC) MAKEPREPOSTVAR(Cot, cot, COT) MAKEPREPOSTVAR(Sinh, sinh, SINH) MAKEPREPOSTVAR(Cosh, cosh, COSH) MAKEPREPOSTVAR(Tanh, tanh, TANH) MAKEPREPOSTVAR(Sech, sech, SECH) MAKEPREPOSTVAR(Csch, csch, CSCH) MAKEPREPOSTVAR(Coth, coth, COTH) MAKEPREPOSTPARVAR(Auger, auger, AUGER) MAKEPREPOSTPARVAR(Flux, flux, FLUX) }