2023-04-25 19:59:54 -04:00
# pragma once
# include "Variation.h"
namespace EmberNs
{
/// <summary>
/// bubble2.
/// </summary>
template < typename T >
class Bubble2Variation : public ParametricVariation < T >
{
public :
Bubble2Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " bubble2 " , eVariationId : : VAR_BUBBLE2 , weight , true )
{
Init ( ) ;
}
PARVARCOPY ( Bubble2Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T t = Zeps ( T ( 0.25 ) * ( helper . m_PrecalcSumSquares + SQR ( helper . In . z ) ) + 1 ) ;
T r = m_Weight / t ;
helper . Out . x = helper . In . x * r * m_X ;
helper . Out . y = helper . In . y * r * m_Y ;
if ( helper . In . z > = 0 )
helper . Out . z = m_Weight * ( helper . In . z + m_Z ) ;
else
helper . Out . z = m_Weight * ( helper . In . z - m_Z ) ;
helper . Out . z + = helper . In . z * r * m_Z ; //The += is intentional.
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string z = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t t = Zeps(fma((real_t)(0.25), fma(vIn.z, vIn.z, precalcSumSquares), (real_t)(1.0))); \n "
< < " \t \t real_t r = " < < weight < < " / t; \n "
< < " \n "
< < " \t \t vOut.x = vIn.x * r * " < < x < < " ; \n "
< < " \t \t vOut.y = vIn.y * r * " < < y < < " ; \n "
< < " \n "
< < " \t \t if (vIn.z >= 0) \n "
< < " \t \t vOut.z = " < < weight < < " * (vIn.z + " < < z < < " ); \n "
< < " \t \t else \n "
< < " \t \t vOut.z = " < < weight < < " * (vIn.z - " < < z < < " ); \n "
< < " \n "
< < " \t \t vOut.z += vIn.z * r * " < < z < < " ; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " bubble2_x " , 1 ) ) ; //Original used a prefix of bubble_, which is incompatible with Ember's design.
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " bubble2_y " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Z , prefix + " bubble2_z " ) ) ;
}
private :
T m_X ;
T m_Y ;
T m_Z ;
} ;
/// <summary>
/// CircleLinear.
/// </summary>
template < typename T >
class CircleLinearVariation : public ParametricVariation < T >
{
public :
CircleLinearVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " CircleLinear " , eVariationId : : VAR_CIRCLELINEAR , weight )
{
Init ( ) ;
}
PARVARCOPY ( CircleLinearVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int m = int ( Floor < T > ( T ( 0.5 ) * helper . In . x / m_Sc ) ) ;
int n = int ( Floor < T > ( T ( 0.5 ) * helper . In . y / m_Sc ) ) ;
int m21 = m * 2 + 1 ;
int n21 = n * 2 + 1 ;
T x = helper . In . x - m21 * m_Sc ;
T y = helper . In . y - n21 * m_Sc ;
T u = Zeps ( VarFuncs < T > : : Hypot ( x , y ) ) ;
T v = ( T ( 0.3 ) + T ( 0.7 ) * DiscreteNoise2 ( m + 10 , n + 3 ) ) * m_Sc ;
T z1 = DiscreteNoise2 ( int ( m + m_Seed ) , n ) ;
if ( ( z1 < m_Dens1 ) & & ( u < v ) )
{
if ( m_Reverse > 0 )
{
if ( z1 < m_Dens1 * m_Dens2 )
{
x * = m_K ;
y * = m_K ;
}
else
{
T z = v / u * ( 1 - m_K ) + m_K ;
x * = z ;
y * = z ;
}
}
else
{
if ( z1 > m_Dens1 * m_Dens2 )
{
x * = m_K ;
y * = m_K ;
}
else
{
T z = v / u * ( 1 - m_K ) + m_K ;
x * = z ;
y * = z ;
}
}
}
helper . Out . x = m_Weight * ( x + m21 * m_Sc ) ;
helper . Out . y = m_Weight * ( y + n21 * m_Sc ) ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string sc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string k = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dens1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dens2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string reverse = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string seed = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int m = (int)floor((real_t)(0.5) * vIn.x / " < < sc < < " ); \n "
< < " \t \t int n = (int)floor((real_t)(0.5) * vIn.y / " < < sc < < " ); \n "
< < " \t \t int m21 = m * 2 + 1; \n "
< < " \t \t int n21 = n * 2 + 1; \n "
< < " \t \t real_t x = vIn.x - m21 * " < < sc < < " ; \n "
< < " \t \t real_t y = vIn.y - n21 * " < < sc < < " ; \n "
< < " \t \t real_t u = Zeps(Hypot(x, y)); \n "
< < " \t \t real_t v = fma(CircleLinearDiscreteNoise2(m + 10, n + 3), (real_t)(0.7), (real_t)(0.3)) * " < < sc < < " ; \n "
< < " \t \t real_t z1 = CircleLinearDiscreteNoise2((int)(m + " < < seed < < " ), n); \n "
< < " \n "
< < " \t \t if ((z1 < " < < dens1 < < " ) && (u < v)) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < reverse < < " > 0) \n "
< < " \t \t { \n "
< < " \t \t if (z1 < " < < dens1 < < " * " < < dens2 < < " ) \n "
< < " \t \t { \n "
< < " \t \t x *= " < < k < < " ; \n "
< < " \t \t y *= " < < k < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t z = fma(v / u, (1 - " < < k < < " ), " < < k < < " ); \n "
< < " \n "
< < " \t \t x *= z; \n "
< < " \t \t y *= z; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if (z1 > " < < dens1 < < " * " < < dens2 < < " ) \n "
< < " \t \t { \n "
< < " \t \t x *= " < < k < < " ; \n "
< < " \t \t y *= " < < k < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t z = fma(v / u, (1 - " < < k < < " ), " < < k < < " ); \n "
< < " \n "
< < " \t \t x *= z; \n "
< < " \t \t y *= z; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * fma((real_t)m21, " < < sc < < " , x); \n "
< < " \t \t vOut.y = " < < weight < < " * fma((real_t)n21, " < < sc < < " , y); \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Hypot " , " Zeps " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" real_t CircleLinearDiscreteNoise2(int x, int y) \n "
" { \n "
" const real_t im = 2147483647; \n "
" const real_t am = 1 / im; \n "
" \n "
" int n = x + y * 57; \n "
" n = (n << 13) ^ n; \n "
" return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am; \n "
" } \n "
" \n " ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Sc , prefix + " CircleLinear_Sc " , 1 , eParamType : : REAL_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_K , prefix + " CircleLinear_K " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dens1 , prefix + " CircleLinear_Dens1 " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dens2 , prefix + " CircleLinear_Dens2 " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Reverse , prefix + " CircleLinear_Reverse " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " CircleLinear_X " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " CircleLinear_Y " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Seed , prefix + " CircleLinear_Seed " , 0 , eParamType : : INTEGER ) ) ;
}
private :
T DiscreteNoise2 ( int x , int y )
{
const T im = T ( 2147483647 ) ;
const T am = ( 1 / im ) ;
int n = x + y * 57 ;
n = ( n < < 13 ) ^ n ;
return ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7fffffff ) * am ;
}
T m_Sc ;
T m_K ;
T m_Dens1 ;
T m_Dens2 ;
T m_Reverse ;
T m_X ;
T m_Y ;
T m_Seed ;
} ;
/// <summary>
/// CircleRand.
/// The original would loop infinitely as x and y approached zero, so put a check for a max of 10 iters.
/// </summary>
template < typename T >
class CircleRandVariation : public ParametricVariation < T >
{
public :
CircleRandVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " CircleRand " , eVariationId : : VAR_CIRCLERAND , weight )
{
Init ( ) ;
}
PARVARCOPY ( CircleRandVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
intmax_t m , n , iters = 0 ;
T x , y , u ;
do
{
x = m_X * ( 1 - 2 * rand . Frand01 < T > ( ) ) ;
y = m_Y * ( 1 - 2 * rand . Frand01 < T > ( ) ) ;
m = Floor < T > ( T ( 0.5 ) * x / m_Sc ) ;
n = Floor < T > ( T ( 0.5 ) * y / m_Sc ) ;
x - = ( m * 2 + 1 ) * m_Sc ;
y - = ( n * 2 + 1 ) * m_Sc ;
u = VarFuncs < T > : : Hypot ( x , y ) ;
if ( + + iters > 10 )
break ;
}
while ( ( DiscreteNoise2 ( int ( m + m_Seed ) , int ( n ) ) > m_Dens ) | | ( u > ( T ( 0.3 ) + T ( 0.7 ) * DiscreteNoise2 ( int ( m + 10 ) , int ( n + 3 ) ) ) * m_Sc ) ) ;
helper . Out . x = m_Weight * ( x + ( m * 2 + 1 ) * m_Sc ) ;
helper . Out . y = m_Weight * ( y + ( n * 2 + 1 ) * m_Sc ) ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string sc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dens = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string seed = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int m, n, iters = 0; \n "
< < " \t \t real_t x, y, u; \n "
< < " \n "
< < " \t \t do \n "
< < " \t \t { \n "
< < " \t \t x = " < < x < < " * (1 - 2 * MwcNext01(mwc)); \n "
< < " \t \t y = " < < y < < " * (1 - 2 * MwcNext01(mwc)); \n "
< < " \t \t m = (int)floor((real_t)(0.5) * x / " < < sc < < " ); \n "
< < " \t \t n = (int)floor((real_t)(0.5) * y / " < < sc < < " ); \n "
< < " \t \t x = x - (m * 2 + 1) * " < < sc < < " ; \n "
< < " \t \t y = y - (n * 2 + 1) * " < < sc < < " ; \n "
< < " \t \t u = Hypot(x, y); \n "
< < " \n "
< < " \t \t if (++iters > 10) \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \t \t while ((CircleRandDiscreteNoise2((int)(m + " < < seed < < " ), n) > " < < dens < < " ) || (u > fma(CircleRandDiscreteNoise2(m + 10, n + 3), (real_t)(0.7), (real_t)(0.3)) * " < < sc < < " )); \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * fma((real_t)(m * 2 + 1), " < < sc < < " , x); \n "
< < " \t \t vOut.y = " < < weight < < " * fma((real_t)(n * 2 + 1), " < < sc < < " , y); \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Hypot " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" real_t CircleRandDiscreteNoise2(int x, int y) \n "
" { \n "
" const real_t im = 2147483647; \n "
" const real_t am = 1 / im; \n "
" \n "
" int n = x + y * 57; \n "
" n = (n << 13) ^ n; \n "
" return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am; \n "
" } \n "
" \n " ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Sc , prefix + " CircleRand_Sc " , 1 , eParamType : : REAL_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dens , prefix + " CircleRand_Dens " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " CircleRand_X " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " CircleRand_Y " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Seed , prefix + " CircleRand_Seed " , 0 , eParamType : : INTEGER ) ) ;
}
private :
T DiscreteNoise2 ( int x , int y )
{
const T im = T ( 2147483647 ) ;
const T am = ( 1 / im ) ;
int n = x + y * 57 ;
n = ( n < < 13 ) ^ n ;
return ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7fffffff ) * am ;
}
T m_Sc ;
T m_Dens ;
T m_X ;
T m_Y ;
T m_Seed ;
} ;
/// <summary>
/// CircleTrans1.
/// The original would loop infinitely as x and y approached zero, so put a check for a max of 10 iters.
/// </summary>
template < typename T >
class CircleTrans1Variation : public ParametricVariation < T >
{
public :
CircleTrans1Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " CircleTrans1 " , eVariationId : : VAR_CIRCLETRANS1 , weight )
{
Init ( ) ;
}
PARVARCOPY ( CircleTrans1Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T ux , uy , u , x , y ;
Trans ( m_X , m_Y , helper . In . x , helper . In . y , & ux , & uy ) ;
intmax_t m = Floor < T > ( T ( 0.5 ) * ux / m_Sc ) ;
intmax_t n = Floor < T > ( T ( 0.5 ) * uy / m_Sc ) ;
x = ux - ( m * 2 + 1 ) * m_Sc ;
y = uy - ( n * 2 + 1 ) * m_Sc ;
u = VarFuncs < T > : : Hypot ( x , y ) ;
if ( ( DiscreteNoise2 ( int ( m + m_Seed ) , int ( n ) ) > m_Dens ) | | ( u > ( T ( 0.3 ) + T ( 0.7 ) * DiscreteNoise2 ( int ( m + 10 ) , int ( n + 3 ) ) ) * m_Sc ) )
{
ux = ux ;
uy = uy ;
}
else
{
CircleR ( & ux , & uy , rand ) ;
}
helper . Out . x = m_Weight * ux ;
helper . Out . y = m_Weight * uy ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string sc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dens = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string seed = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t ux, uy, u, x, y; \n "
< < " \n "
< < " \t \t CircleTrans1Trans( " < < x < < " , " < < y < < " , vIn.x, vIn.y, &ux, &uy); \n "
< < " \n "
< < " \t \t int m = (int)floor((real_t)(0.5) * ux / " < < sc < < " ); \n "
< < " \t \t int n = (int)floor((real_t)(0.5) * uy / " < < sc < < " ); \n "
< < " \n "
< < " \t \t x = ux - (m * 2 + 1) * " < < sc < < " ; \n "
< < " \t \t y = uy - (n * 2 + 1) * " < < sc < < " ; \n "
< < " \t \t u = Hypot(x, y); \n "
< < " \n "
< < " \t \t if ((CircleTrans1DiscreteNoise2((int)(m + " < < seed < < " ), n) > " < < dens < < " ) || (u > fma(CircleTrans1DiscreteNoise2(m + 10, n + 3), (real_t)(0.7), (real_t)(0.3)) * " < < sc < < " )) \n "
< < " \t \t { \n "
< < " \t \t ux = ux; \n "
< < " \t \t uy = uy; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t CircleTrans1CircleR( " < < x < < " , " < < y < < " , " < < sc < < " , " < < seed < < " , " < < dens < < " , &ux, &uy, mwc); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * ux; \n "
< < " \t \t vOut.y = " < < weight < < " * uy; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" real_t CircleTrans1DiscreteNoise2(int x, int y) \n "
" { \n "
" const real_t im = 2147483647; \n "
" const real_t am = 1 / im; \n "
" \n "
" int n = x + y * 57; \n "
" n = (n << 13) ^ n; \n "
" return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am; \n "
" } \n "
" \n "
" void CircleTrans1Trans(real_t a, real_t b, real_t x, real_t y, real_t* x1, real_t* y1) \n "
" { \n "
" *x1 = fma((x - a), (real_t)(0.5), a); \n "
" *y1 = fma((y - b), (real_t)(0.5), b); \n "
" } \n "
" \n "
" void CircleTrans1CircleR(real_t mx, real_t my, real_t sc, real_t seed, real_t dens, real_t* ux, real_t* vy, uint2* mwc) \n "
" { \n "
" int m, n, iters = 0; \n "
" real_t x, y, alpha, u; \n "
" \n "
" do \n "
" { \n "
" x = fabs(mx) * (1 - 2 * MwcNext01(mwc)); \n "
" y = fabs(my) * (1 - 2 * MwcNext01(mwc)); \n "
" m = (int)floor((real_t)(0.5) * x / sc); \n "
" n = (int)floor((real_t)(0.5) * y / sc); \n "
" alpha = M_2PI * MwcNext01(mwc); \n "
" u = fma(CircleTrans1DiscreteNoise2(m + 10, n + 3), (real_t)(0.7), (real_t)(0.3)); \n "
" x = u * cos(alpha); \n "
" y = u * sin(alpha); \n "
" \n "
" if (++iters > 10) \n "
" break; \n "
" } \n "
" while (CircleTrans1DiscreteNoise2((int)(m + seed), n) > dens); \n "
" \n "
" *ux = fma((real_t)(m * 2 + 1), sc, x); \n "
" *vy = fma((real_t)(n * 2 + 1), sc, y); \n "
" } \n "
" \n " ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Hypot " } ;
}
virtual void Precalc ( ) override
{
m_Sc = Zeps ( m_Sc ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Sc , prefix + " CircleTrans1_Sc " , 1 , eParamType : : REAL_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dens , prefix + " CircleTrans1_Dens " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " CircleTrans1_X " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " CircleTrans1_Y " , 10 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Seed , prefix + " CircleTrans1_Seed " , 0 , eParamType : : INTEGER ) ) ;
}
private :
T DiscreteNoise2 ( int x , int y )
{
const T im = T ( 2147483647 ) ;
const T am = ( 1 / im ) ;
int n = x + y * 57 ;
n = ( n < < 13 ) ^ n ;
return ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7fffffff ) * am ;
}
void Trans ( T a , T b , T x , T y , T * x1 , T * y1 )
{
* x1 = ( x - a ) * T ( 0.5 ) + a ;
* y1 = ( y - b ) * T ( 0.5 ) + b ;
}
void CircleR ( T * ux , T * vy , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand )
{
intmax_t m , n , iters = 0 ;
T x , y , alpha , u ;
do
{
x = std : : abs ( m_X ) * ( 1 - 2 * rand . Frand01 < T > ( ) ) ;
y = std : : abs ( m_Y ) * ( 1 - 2 * rand . Frand01 < T > ( ) ) ;
m = Floor < T > ( T ( 0.5 ) * x / m_Sc ) ;
n = Floor < T > ( T ( 0.5 ) * y / m_Sc ) ;
alpha = M_2PI * rand . Frand01 < T > ( ) ;
u = T ( 0.3 ) + T ( 0.7 ) * DiscreteNoise2 ( int ( m + 10 ) , int ( n + 3 ) ) ;
x = u * std : : cos ( alpha ) ;
y = u * std : : sin ( alpha ) ;
if ( + + iters > 10 )
break ;
}
while ( DiscreteNoise2 ( int ( m + m_Seed ) , int ( n ) ) > m_Dens ) ;
* ux = x + ( m * 2 + 1 ) * m_Sc ;
* vy = y + ( n * 2 + 1 ) * m_Sc ;
}
T m_Sc ;
T m_Dens ;
T m_X ;
T m_Y ;
T m_Seed ;
} ;
/// <summary>
/// cubic3D.
/// </summary>
template < typename T >
class Cubic3DVariation : public ParametricVariation < T >
{
public :
Cubic3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " cubic3D " , eVariationId : : VAR_CUBIC3D , weight )
{
Init ( ) ;
}
PARVARCOPY ( Cubic3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int useNode = rand . Rand ( ) & 7 ; //Faster than % 8.
T exnze , wynze , znxy ;
T px , py , pz ;
exnze = 1 - ( m_SmoothStyle * ( 1 - ( std : : cos ( std : : atan2 ( helper . In . x , helper . In . z ) ) ) ) ) ;
wynze = 1 - ( m_SmoothStyle * ( 1 - ( std : : sin ( std : : atan2 ( helper . In . y , helper . In . z ) ) ) ) ) ;
if ( m_SmoothStyle > 1 )
znxy = 1 - ( m_SmoothStyle * ( 1 - ( ( exnze + wynze ) / 2 * m_SmoothStyle ) ) ) ;
else
znxy = 1 - ( m_SmoothStyle * ( 1 - ( ( exnze + wynze ) * T ( 0.5 ) ) ) ) ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
px = helper . In . x ;
py = helper . In . y ;
pz = helper . In . z ;
}
else
{
px = outPoint . m_X ;
py = outPoint . m_Y ;
pz = outPoint . m_Z ;
}
T val1 = ( px - ( m_Smooth1mFill * px * exnze ) ) + ( helper . In . x * m_SmoothFill * exnze ) ;
T val2 = ( py - ( m_Smooth1mFill * py * wynze ) ) + ( helper . In . y * m_SmoothFill * wynze ) ;
T val3 = ( pz - ( m_Smooth1mFill * pz * znxy ) ) + ( helper . In . z * m_SmoothFill * znxy ) ;
switch ( useNode )
{
case 0 :
helper . Out . x = val1 + m_HalfWeight ;
helper . Out . y = val2 + m_HalfWeight ;
helper . Out . z = val3 + m_HalfWeight ;
break ;
case 1 :
helper . Out . x = val1 + m_HalfWeight ;
helper . Out . y = val2 - m_HalfWeight ;
helper . Out . z = val3 + m_HalfWeight ;
break ;
case 2 :
helper . Out . x = val1 + m_HalfWeight ;
helper . Out . y = val2 + m_HalfWeight ;
helper . Out . z = val3 - m_HalfWeight ;
break ;
case 3 :
helper . Out . x = val1 + m_HalfWeight ;
helper . Out . y = val2 - m_HalfWeight ;
helper . Out . z = val3 - m_HalfWeight ;
break ;
case 4 :
helper . Out . x = val1 - m_HalfWeight ;
helper . Out . y = val2 + m_HalfWeight ;
helper . Out . z = val3 + m_HalfWeight ;
break ;
case 5 :
helper . Out . x = val1 - m_HalfWeight ;
helper . Out . y = val2 - m_HalfWeight ;
helper . Out . z = val3 + m_HalfWeight ;
break ;
case 6 :
helper . Out . x = val1 - m_HalfWeight ;
helper . Out . y = val2 + m_HalfWeight ;
helper . Out . z = val3 - m_HalfWeight ;
break ;
case 7 :
default :
helper . Out . x = val1 - m_HalfWeight ;
helper . Out . y = val2 - m_HalfWeight ;
helper . Out . z = val3 - m_HalfWeight ;
break ;
}
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string xpand = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string style = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string fill = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string smooth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string smoothStyle = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string smoothfill = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string smooth1mfill = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string halfweight = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int useNode = MwcNext(mwc) & 7; \n "
< < " \t \t real_t exnze, wynze, znxy; \n "
< < " \t \t real_t px, py, pz; \n "
< < " \n "
< < " \t \t exnze = 1 - ( " < < smoothStyle < < " * (1 - (cos(atan2(vIn.x, vIn.z))))); \n "
< < " \t \t wynze = 1 - ( " < < smoothStyle < < " * (1 - (sin(atan2(vIn.y, vIn.z))))); \n "
< < " \n "
< < " \t \t if ( " < < smoothStyle < < " > 1) \n "
< < " \t \t znxy = 1 - ( " < < smoothStyle < < " * (1 - ((exnze + wynze) / 2 * " < < smoothStyle < < " ))); \n "
< < " \t \t else \n "
< < " \t \t znxy = 1 - ( " < < smoothStyle < < " * (1 - ((exnze + wynze) * (real_t)(0.5)))); \n \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
ss < <
" \t \t px = vIn.x; \n "
" \t \t py = vIn.y; \n "
" \t \t pz = vIn.z; \n \n " ;
}
else
{
ss < <
" \t \t px = outPoint->m_X; \n "
" \t \t py = outPoint->m_Y; \n "
" \t \t pz = outPoint->m_Z; \n \n " ;
}
ss < <
" \t \t real_t val1 = (px - ( " < < smooth1mfill < < " * px * exnze)) + (vIn.x * " < < smoothfill < < " * exnze); \n "
" \t \t real_t val2 = (py - ( " < < smooth1mfill < < " * py * wynze)) + (vIn.y * " < < smoothfill < < " * wynze); \n "
" \t \t real_t val3 = (pz - ( " < < smooth1mfill < < " * pz * znxy)) + (vIn.z * " < < smoothfill < < " * znxy); \n "
" \n "
" \t \t switch (useNode) \n "
" \t \t { \n "
" \t \t case 0: \n "
" \t \t vOut.x = val1 + " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 + " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 + " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 1: \n "
" \t \t vOut.x = val1 + " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 - " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 + " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 2: \n "
" \t \t vOut.x = val1 + " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 + " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 - " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 3: \n "
" \t \t vOut.x = val1 + " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 - " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 - " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 4: \n "
" \t \t vOut.x = val1 - " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 + " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 + " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 5: \n "
" \t \t vOut.x = val1 - " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 - " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 + " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 6: \n "
" \t \t vOut.x = val1 - " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 + " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 - " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t case 7: \n "
" \t \t default: \n "
" \t \t vOut.x = val1 - " < < halfweight < < " ; \n "
" \t \t vOut.y = val2 - " < < halfweight < < " ; \n "
" \t \t vOut.z = val3 - " < < halfweight < < " ; \n "
" \t \t break; \n "
" \t \t } \n "
" \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
if ( std : : abs ( m_Xpand ) < = 1 )
m_Fill = m_Xpand * T ( 0.5 ) ;
else
m_Fill = std : : sqrt ( m_Xpand ) * T ( 0.5 ) ;
if ( std : : abs ( m_Weight ) < = T ( 0.5 ) )
m_Smooth = m_Weight * 2 ; //Causes full effect above m_Weight = 0.5.
else
m_Smooth = 1 ;
if ( std : : abs ( m_Style ) < = 1 )
{
m_SmoothStyle = m_Style ;
}
else
{
if ( m_Style > 1 )
m_SmoothStyle = 1 + ( m_Style - 1 ) * T ( 0.25 ) ;
else
m_SmoothStyle = ( m_Style + 1 ) * T ( 0.25 ) - 1 ;
}
m_SmoothFill = m_Smooth * m_Fill ;
m_Smooth1mFill = m_Smooth * ( 1 - m_Fill ) ;
m_HalfWeight = m_Weight * T ( 0.5 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Xpand , prefix + " cubic3D_xpand " , T ( 0.25 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Style , prefix + " cubic3D_style " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Fill , prefix + " cubic3D_fill " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_Smooth , prefix + " cubic3D_smooth " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SmoothStyle , prefix + " cubic3D_smooth_style " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SmoothFill , prefix + " cubic3D_smooth_fill " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Smooth1mFill , prefix + " cubic3D_smooth_1m_fill " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HalfWeight , prefix + " cubic3D_half_weight " ) ) ;
}
private :
T m_Xpand ;
T m_Style ;
T m_Fill ; //Precalc.
T m_Smooth ;
T m_SmoothStyle ;
T m_SmoothFill ;
T m_Smooth1mFill ;
T m_HalfWeight ;
} ;
/// <summary>
/// cubicLattice_3D.
/// </summary>
template < typename T >
class CubicLattice3DVariation : public ParametricVariation < T >
{
public :
CubicLattice3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " cubicLattice_3D " , eVariationId : : VAR_CUBIC_LATTICE3D , weight )
{
Init ( ) ;
}
PARVARCOPY ( CubicLattice3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int useNode = rand . Rand ( ) & 7 ; //Faster than % 8.
T exnze , wynze , znxy , px , py , pz ;
if ( m_Style = = 2 )
{
exnze = std : : cos ( std : : atan2 ( helper . In . x , helper . In . z ) ) ;
wynze = std : : sin ( std : : atan2 ( helper . In . y , helper . In . z ) ) ;
znxy = ( exnze + wynze ) * T ( 0.5 ) ;
}
else
{
exnze = 1 ;
wynze = 1 ;
znxy = 1 ;
}
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
px = helper . In . x ;
py = helper . In . y ;
pz = helper . In . z ;
}
else
{
px = outPoint . m_X ;
py = outPoint . m_Y ;
pz = outPoint . m_Z ;
}
T pxtx = ( px + helper . In . x ) * m_Fill * exnze ;
T pyty = ( py + helper . In . y ) * m_Fill * wynze ;
T pztz = ( pz + helper . In . z ) * m_Fill * znxy ;
switch ( useNode )
{
case 0 :
helper . Out . x = pxtx + m_Weight ;
helper . Out . y = pyty + m_Weight ;
helper . Out . z = pztz + m_Weight ;
break ;
case 1 :
helper . Out . x = pxtx + m_Weight ;
helper . Out . y = pyty - m_Weight ;
helper . Out . z = pztz + m_Weight ;
break ;
case 2 :
helper . Out . x = pxtx + m_Weight ;
helper . Out . y = pyty + m_Weight ;
helper . Out . z = pztz - m_Weight ;
break ;
case 3 :
helper . Out . x = pxtx + m_Weight ;
helper . Out . y = pyty - m_Weight ;
helper . Out . z = pztz - m_Weight ;
break ;
case 4 :
helper . Out . x = pxtx - m_Weight ;
helper . Out . y = pyty + m_Weight ;
helper . Out . z = pztz + m_Weight ;
break ;
case 5 :
helper . Out . x = pxtx - m_Weight ;
helper . Out . y = pyty - m_Weight ;
helper . Out . z = pztz + m_Weight ;
break ;
case 6 :
helper . Out . x = pxtx - m_Weight ;
helper . Out . y = pyty + m_Weight ;
helper . Out . z = pztz - m_Weight ;
break ;
case 7 :
default :
helper . Out . x = pxtx - m_Weight ;
helper . Out . y = pyty - m_Weight ;
helper . Out . z = pztz - m_Weight ;
break ;
}
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string xpand = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string style = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string fill = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int useNode = MwcNext(mwc) & 7; \n "
< < " \t \t real_t exnze, wynze, znxy, px, py, pz; \n "
< < " \n "
< < " \t \t if ( " < < style < < " == 2) \n "
< < " \t \t { \n "
< < " \t \t exnze = cos(atan2(vIn.x, vIn.z)); \n "
< < " \t \t wynze = sin(atan2(vIn.y, vIn.z)); \n "
< < " \t \t znxy = (exnze + wynze) * (real_t)(0.5); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t exnze = 1; \n "
< < " \t \t wynze = 1; \n "
< < " \t \t znxy = 1; \n "
< < " \t \t } \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
ss < <
" \t \t px = vIn.x; \n "
" \t \t py = vIn.y; \n "
" \t \t pz = vIn.z; \n " ;
}
else
{
ss < <
" \t \t px = outPoint->m_X; \n "
" \t \t py = outPoint->m_Y; \n "
" \t \t pz = outPoint->m_Z; \n " ;
}
ss < < " \t \t real_t pxtx = (px + vIn.x) * " < < fill < < " * exnze; \n "
< < " \t \t real_t pyty = (py + vIn.y) * " < < fill < < " * wynze; \n "
< < " \t \t real_t pztz = (pz + vIn.z) * " < < fill < < " * znxy ; \n "
< < " \n "
< < " \t \t switch (useNode) \n "
< < " \t \t { \n "
< < " \t \t case 0: \n "
< < " \t \t vOut.x = pxtx + " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty + " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz + " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 1: \n "
< < " \t \t vOut.x = pxtx + " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty - " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz + " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 2: \n "
< < " \t \t vOut.x = pxtx + " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty + " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz - " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 3: \n "
< < " \t \t vOut.x = pxtx + " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty - " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz - " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 4: \n "
< < " \t \t vOut.x = pxtx - " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty + " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz + " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 5: \n "
< < " \t \t vOut.x = pxtx - " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty - " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz + " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 6: \n "
< < " \t \t vOut.x = pxtx - " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty + " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz - " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t case 7: \n "
< < " \t \t default: \n "
< < " \t \t vOut.x = pxtx - " < < weight < < " ; \n "
< < " \t \t vOut.y = pyty - " < < weight < < " ; \n "
< < " \t \t vOut.z = pztz - " < < weight < < " ; \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
if ( std : : abs ( m_Xpand ) < = 1 )
m_Fill = m_Xpand * T ( 0.5 ) ;
else
m_Fill = std : : sqrt ( m_Xpand ) * T ( 0.5 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Xpand , prefix + " cubicLattice_3D_xpand " , T ( 0.2 ) ) ) ; //Original used a prefix of cubic3D_, which is incompatible with Ember's design.
m_Params . push_back ( ParamWithName < T > ( & m_Style , prefix + " cubicLattice_3D_style " , 1 , eParamType : : INTEGER , 1 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Fill , prefix + " cubicLattice_3D_fill " ) ) ; //Precalc.
}
private :
T m_Xpand ;
T m_Style ;
T m_Fill ; //Precalc.
} ;
/// <summary>
/// foci_3D.
/// </summary>
template < typename T >
class Foci3DVariation : public Variation < T >
{
public :
Foci3DVariation ( T weight = 1.0 ) : Variation < T > ( " foci_3D " , eVariationId : : VAR_FOCI3D , weight , false , false , false , false , true ) { }
VARCOPY ( Foci3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T expx = std : : exp ( helper . In . x ) * T ( 0.5 ) ;
T expnx = T ( 0.25 ) / Zeps ( expx ) ;
T boot = helper . In . z = = 0 ? helper . m_PrecalcAtanyx : helper . In . z ;
T tmp = m_Weight / Zeps ( expx + expnx - ( std : : cos ( helper . In . y ) * std : : cos ( boot ) ) ) ;
helper . Out . x = ( expx - expnx ) * tmp ;
helper . Out . y = std : : sin ( helper . In . y ) * tmp ;
helper . Out . z = std : : sin ( boot ) * tmp ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss ;
string weight = WeightDefineString ( ) ;
ss < < " \t { \n "
< < " \t \t real_t expx = exp(vIn.x) * (real_t)(0.5); \n "
< < " \t \t real_t expnx = (real_t)(0.25) / Zeps(expx); \n "
< < " \t \t real_t boot = vIn.z == 0 ? precalcAtanyx : vIn.z; \n "
< < " \t \t real_t tmp = " < < weight < < " / Zeps(expx + expnx - (cos(vIn.y) * cos(boot))); \n "
< < " \n "
< < " \t \t vOut.x = (expx - expnx) * tmp; \n "
< < " \t \t vOut.y = sin(vIn.y) * tmp; \n "
< < " \t \t vOut.z = sin(boot) * tmp; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
} ;
/// <summary>
/// foci_p.
/// Idea by Chaosfissure.
/// </summary>
template < typename T >
class FociPVariation : public ParametricVariation < T >
{
public :
FociPVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " foci_p " , eVariationId : : VAR_FOCI_P , weight )
{
Init ( ) ;
}
PARVARCOPY ( FociPVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T exp_x = Zeps ( std : : exp ( helper . In . x ) ) ;
T exp_x_2 = exp_x * m_C1 ;
T exp_nz = m_C2 / exp_x ;
T cos_y = std : : cos ( helper . In . y ) ;
T sin_y = std : : sin ( helper . In . y ) ;
T r = m_Weight / Zeps ( exp_x_2 + exp_nz - cos_y ) ;
helper . Out . x = ( exp_x_2 - exp_nz ) * r ;
helper . Out . y = sin_y * r ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string c1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string c2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t exp_x = Zeps(exp(vIn.x)); \n "
< < " \t \t real_t exp_x_2 = exp_x * " < < c1 < < " ; \n "
< < " \t \t real_t exp_nz = " < < c2 < < " / exp_x; \n "
< < " \t \t real_t cos_y = cos(vIn.y); \n "
< < " \t \t real_t sin_y = sin(vIn.y); \n "
< < " \t \t real_t r = " < < weight < < " / Zeps(exp_x_2 + exp_nz - cos_y); \n "
< < " \n "
< < " \t \t vOut.x = (exp_x_2 - exp_nz) * r; \n "
< < " \t \t vOut.y = sin_y * r; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_C1 , prefix + " foci_p_c1 " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_C2 , prefix + " foci_p_c2 " , T ( 0.5 ) ) ) ;
}
private :
T m_C1 ;
T m_C2 ;
} ;
/// <summary>
/// ho.
/// </summary>
template < typename T >
class HoVariation : public ParametricVariation < T >
{
public :
HoVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " ho " , eVariationId : : VAR_HO , weight )
{
Init ( ) ;
}
PARVARCOPY ( HoVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T uu = SQR ( helper . In . x ) ;
T vv = SQR ( helper . In . y ) ;
T ww = SQR ( helper . In . z ) ;
T atOmegaX = std : : atan2 ( vv , ww ) ;
T atOmegaY = std : : atan2 ( uu , ww ) ;
T su = std : : sin ( helper . In . x ) ;
T cu = std : : cos ( helper . In . x ) ;
T sv = std : : sin ( helper . In . y ) ;
T cv = std : : cos ( helper . In . y ) ;
T cucv = cu * cv ;
T sucv = su * cv ;
T x = std : : pow ( std : : abs ( cucv ) , m_XPow ) + ( cucv * m_XPow ) + ( T ( 0.25 ) * atOmegaX ) ; //Must fabs first argument to pow, because negative values will return NaN.
T y = std : : pow ( std : : abs ( sucv ) , m_YPow ) + ( sucv * m_YPow ) + ( T ( 0.25 ) * atOmegaY ) ; //Original did not do this and would frequently return bad values.
T z = std : : pow ( std : : abs ( sv ) , m_ZPow ) + sv * m_ZPow ;
helper . Out . x = m_Weight * x ;
helper . Out . y = m_Weight * y ;
helper . Out . z = m_Weight * z ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string xpow = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ypow = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string zpow = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t uu = SQR(vIn.x); \n "
< < " \t \t real_t vv = SQR(vIn.y); \n "
< < " \t \t real_t ww = SQR(vIn.z); \n "
< < " \t \t real_t atOmegaX = atan2(vv, ww); \n "
< < " \t \t real_t atOmegaY = atan2(uu, ww); \n "
< < " \t \t real_t su = sin(vIn.x); \n "
< < " \t \t real_t cu = cos(vIn.x); \n "
< < " \t \t real_t sv = sin(vIn.y); \n "
< < " \t \t real_t cv = cos(vIn.y); \n "
< < " \t \t real_t cucv = cu * cv; \n "
< < " \t \t real_t sucv = su * cv; \n "
< < " \t \t real_t x = pow(fabs(cucv), " < < xpow < < " ) + fma(cucv, " < < xpow < < " , (real_t)(0.25) * atOmegaX); \n "
< < " \t \t real_t y = pow(fabs(sucv), " < < ypow < < " ) + fma(sucv, " < < ypow < < " , (real_t)(0.25) * atOmegaY); \n "
< < " \t \t real_t z = fma(sv, " < < zpow < < " , pow(fabs(sv), " < < zpow < < " )); \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * x; \n "
< < " \t \t vOut.y = " < < weight < < " * y; \n "
< < " \t \t vOut.z = " < < weight < < " * z; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_XPow , prefix + " ho_xpow " , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_YPow , prefix + " ho_ypow " , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ZPow , prefix + " ho_zpow " , 3 ) ) ;
}
private :
T m_XPow ;
T m_YPow ;
T m_ZPow ;
} ;
/// <summary>
/// Julia3Dq.
/// </summary>
template < typename T >
class Julia3DqVariation : public ParametricVariation < T >
{
public :
Julia3DqVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " julia3Dq " , eVariationId : : VAR_JULIA3DQ , weight , true , true , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Julia3DqVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T temp = helper . m_PrecalcAtanyx * m_InvPower + rand . Crand ( ) * m_InvPower2pi ;
T sina = std : : sin ( temp ) ;
T cosa = std : : cos ( temp ) ;
T z = helper . In . z * m_AbsInvPower ;
T r2d = helper . m_PrecalcSumSquares ;
T r = m_Weight * std : : pow ( r2d + SQR ( z ) , m_HalfInvPower ) ;
T rsss = r * helper . m_PrecalcSqrtSumSquares ;
helper . Out . x = rsss * cosa ;
helper . Out . y = rsss * sina ;
helper . Out . z = r * z ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string power = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string divisor = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invPower = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string absInvPower = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string halfInvPower = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invPower2pi = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t temp = fma(precalcAtanyx, " < < invPower < < " , MwcNextCrand(mwc) * " < < invPower2pi < < " ); \n "
< < " \t \t real_t sina = sin(temp); \n "
< < " \t \t real_t cosa = cos(temp); \n "
< < " \t \t real_t z = vIn.z * " < < absInvPower < < " ; \n "
< < " \t \t real_t r2d = precalcSumSquares; \n "
< < " \t \t real_t r = " < < weight < < " * pow(fma(z, z, r2d), " < < halfInvPower < < " ); \n "
< < " \t \t real_t rsss = r * precalcSqrtSumSquares; \n "
< < " \n "
< < " \t \t vOut.x = rsss * cosa; \n "
< < " \t \t vOut.y = rsss * sina; \n "
< < " \t \t vOut.z = r * z; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_InvPower = m_Divisor / m_Power ;
m_AbsInvPower = std : : abs ( m_InvPower ) ;
m_HalfInvPower = T ( 0.5 ) * m_InvPower - T ( 0.5 ) ;
m_InvPower2pi = M_2PI / m_Power ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Power , prefix + " julia3Dq_power " , 3 , eParamType : : INTEGER_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Divisor , prefix + " julia3Dq_divisor " , 2 , eParamType : : INTEGER_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_InvPower , prefix + " julia3Dq_inv_power " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsInvPower , prefix + " julia3Dq_abs_inv_power " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HalfInvPower , prefix + " julia3Dq_half_inv_power " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_InvPower2pi , prefix + " julia3Dq_inv_power_2pi " ) ) ;
}
private :
T m_Power ;
T m_Divisor ;
T m_InvPower ; //Precalc.
T m_AbsInvPower ;
T m_HalfInvPower ;
T m_InvPower2pi ;
} ;
/// <summary>
/// line.
/// </summary>
template < typename T >
class LineVariation : public ParametricVariation < T >
{
public :
LineVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " line " , eVariationId : : VAR_LINE , weight )
{
Init ( ) ;
}
PARVARCOPY ( LineVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T r = rand . Frand01 < T > ( ) * m_Weight ;
helper . Out . x = m_Ux * r ;
helper . Out . y = m_Uy * r ;
helper . Out . z = m_Uz * r ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string delta = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string phi = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ux = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string uy = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string uz = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t r = MwcNext01(mwc) * " < < weight < < " ; \n "
< < " \n "
< < " \t \t vOut.x = " < < ux < < " * r; \n "
< < " \t \t vOut.y = " < < uy < < " * r; \n "
< < " \t \t vOut.z = " < < uz < < " * r; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
//Unit vector of the line.
m_Ux = std : : cos ( m_Delta * T ( M_PI ) ) * std : : cos ( m_Phi * T ( M_PI ) ) ;
m_Uy = std : : sin ( m_Delta * T ( M_PI ) ) * std : : cos ( m_Phi * T ( M_PI ) ) ;
m_Uz = std : : sin ( m_Phi * T ( M_PI ) ) ;
T r = std : : sqrt ( SQR ( m_Ux ) + SQR ( m_Uy ) + SQR ( m_Uz ) ) ;
//Normalize.
m_Ux / = r ;
m_Uy / = r ;
m_Uz / = r ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Delta , prefix + " line_delta " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Phi , prefix + " line_phi " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ux , prefix + " line_ux " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_Uy , prefix + " line_uy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Uz , prefix + " line_uz " ) ) ;
}
private :
T m_Delta ;
T m_Phi ;
T m_Ux ; //Precalc.
T m_Uy ;
T m_Uz ;
} ;
/// <summary>
/// Loonie2.
/// </summary>
template < typename T >
class Loonie2Variation : public ParametricVariation < T >
{
public :
Loonie2Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " loonie2 " , eVariationId : : VAR_LOONIE2 , weight , true , true )
{
Init ( ) ;
}
PARVARCOPY ( Loonie2Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int i ;
T xrt = helper . In . x , yrt = helper . In . y , swp ;
T r2 = xrt * m_Coss + std : : abs ( yrt ) * m_Sins ;
T circle = helper . m_PrecalcSqrtSumSquares ;
for ( i = 0 ; i < m_Sides - 1 ; i + + )
{
swp = xrt * m_Cosa - yrt * m_Sina ;
yrt = xrt * m_Sina + yrt * m_Cosa ;
xrt = swp ;
r2 = std : : max ( r2 , xrt * m_Coss + std : : abs ( yrt ) * m_Sins ) ;
}
r2 = r2 * m_Cosc + circle * m_Sinc ;
if ( i > 1 )
r2 = SQR ( r2 ) ;
else
r2 = std : : abs ( r2 ) * r2 ;
if ( r2 > 0 & & ( r2 < m_W2 ) )
{
T r = m_Weight * std : : sqrt ( std : : abs ( m_W2 / r2 - 1 ) ) ;
helper . Out . x = r * helper . In . x ;
helper . Out . y = r * helper . In . y ;
}
else if ( r2 < 0 )
{
T r = m_Weight / std : : sqrt ( std : : abs ( m_W2 / r2 ) - 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 = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) ;
string sides = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string star = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string circle = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string w2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string sina = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cosa = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string sins = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string coss = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string sinc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cosc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int i; \n "
< < " \t \t real_t xrt = vIn.x, yrt = vIn.y, swp; \n "
< < " \t \t real_t r2 = fma(xrt, " < < coss < < " , fabs(yrt) * " < < sins < < " ); \n "
< < " \t \t real_t circle = precalcSqrtSumSquares; \n "
< < " \n "
< < " \t \t for (i = 0; i < " < < sides < < " - 1; i++) \n "
< < " \t \t { \n "
< < " \t \t swp = fma(xrt, " < < cosa < < " , -(yrt * " < < sina < < " )); \n "
< < " \t \t yrt = fma(xrt, " < < sina < < " , yrt * " < < cosa < < " ); \n "
< < " \t \t xrt = swp; \n "
< < " \n "
< < " \t \t r2 = max(r2, fma(xrt, " < < coss < < " , fabs(yrt) * " < < sins < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t r2 = fma(r2, " < < cosc < < " , circle * " < < sinc < < " ); \n "
< < " \n "
< < " \t \t if (i > 1) \n "
< < " \t \t r2 = SQR(r2); \n "
< < " \t \t else \n "
< < " \t \t r2 = fabs(r2) * r2; \n "
< < " \n "
< < " \t \t if (r2 > 0 && (r2 < " < < w2 < < " )) \n "
< < " \t \t { \n "
< < " \t \t real_t r = " < < weight < < " * sqrt(fabs( " < < w2 < < " / r2 - 1)); \n "
< < " \n "
< < " \t \t vOut.x = r * vIn.x; \n "
< < " \t \t vOut.y = r * vIn.y; \n "
< < " \t \t } \n "
< < " \t \t else if (r2 < 0) \n "
< < " \t \t { \n "
< < " \t \t real_t r = " < < weight < < " / sqrt(fabs( " < < w2 < < " / r2) - 1); \n "
< < " \n "
< < " \t \t vOut.x = r * vIn.x; \n "
< < " \t \t vOut.y = r * vIn.y; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < weight < < " * vIn.x; \n "
< < " \t \t vOut.y = " < < weight < < " * vIn.y; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
auto a = M_2PI / m_Sides ;
auto s = T ( - M_PI_2 ) * m_Star ;
auto c = T ( M_PI_2 ) * m_Circle ;
m_W2 = SQR ( m_Weight ) ;
sincos ( a , & m_Sina , & m_Cosa ) ;
sincos ( s , & m_Sins , & m_Coss ) ;
sincos ( c , & m_Sinc , & m_Cosc ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Sides , prefix + " loonie2_sides " , 4 , eParamType : : INTEGER , 1 , 50 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Star , prefix + " loonie2_star " , 0 , eParamType : : REAL , - 1 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Circle , prefix + " loonie2_circle " , 0 , eParamType : : REAL , - 1 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_W2 , prefix + " loonie2_w2 " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_Sina , prefix + " loonie2_sina " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Cosa , prefix + " loonie2_cosa " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Sins , prefix + " loonie2_sins " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Coss , prefix + " loonie2_coss " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Sinc , prefix + " loonie2_sinc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Cosc , prefix + " loonie2_cosc " ) ) ;
}
private :
T m_Sides ;
T m_Star ;
T m_Circle ;
T m_W2 ; //Precalc.
T m_Sina ;
T m_Cosa ;
T m_Sins ;
T m_Coss ;
T m_Sinc ;
T m_Cosc ;
} ;
/// <summary>
/// Loonie3.
/// </summary>
template < typename T >
class Loonie3Variation : public ParametricVariation < T >
{
public :
Loonie3Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " loonie3 " , eVariationId : : VAR_LOONIE3 , weight , true )
{
Init ( ) ;
}
PARVARCOPY ( Loonie3Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T r2 ;
if ( helper . In . x > EPS )
r2 = SQR ( helper . m_PrecalcSumSquares / helper . In . x ) ;
else
r2 = 2 * m_W2 ;
if ( r2 < m_W2 )
{
T r = m_Weight * std : : sqrt ( m_W2 / r2 - 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 = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string w2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t r2; \n "
< < " \n "
< < " \t \t if (vIn.x > EPS) \n "
< < " \t \t r2 = SQR(precalcSumSquares / vIn.x); \n "
< < " \t \t else \n "
< < " \t \t r2 = 2 * " < < w2 < < " ; \n "
< < " \n "
< < " \t \t if (r2 < " < < w2 < < " ) \n "
< < " \t \t { \n "
< < " \t \t real_t r = " < < weight < < " * sqrt( " < < w2 < < " / r2 - 1); \n "
< < " \n "
< < " \t \t vOut.x = r * vIn.x; \n "
< < " \t \t vOut.y = r * vIn.y; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < weight < < " * vIn.x; \n "
< < " \t \t vOut.y = " < < weight < < " * vIn.y; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_W2 = SQR ( m_Weight ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_W2 , prefix + " loonie3_w2 " ) ) ; //Precalc.
}
private :
T m_W2 ; //Precalc.
} ;
/// <summary>
/// loonie_3D.
/// </summary>
template < typename T >
class Loonie3DVariation : public ParametricVariation < T >
{
public :
Loonie3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " loonie_3D " , eVariationId : : VAR_LOONIE3D , weight , true , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Loonie3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T kikr = helper . m_PrecalcAtanyx ;
T efTez = helper . In . z = = 0 ? kikr : helper . In . z ;
T r2 = helper . m_PrecalcSumSquares + SQR ( efTez ) ;
if ( r2 < m_Vv )
{
T r = m_Weight * std : : sqrt ( m_Vv / r2 - 1 ) ;
helper . Out . x = r * helper . In . x ;
helper . Out . y = r * helper . In . y ;
helper . Out . z = r * efTez * T ( 0.5 ) ;
}
else
{
helper . Out . x = m_Weight * helper . In . x ;
helper . Out . y = m_Weight * helper . In . y ;
helper . Out . z = m_Weight * efTez * T ( 0.5 ) ;
}
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string vv = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t kikr = precalcAtanyx; \n "
< < " \t \t real_t efTez = vIn.z == 0 ? kikr : vIn.z; \n "
< < " \t \t real_t r2 = fma(efTez, efTez, precalcSumSquares); \n "
< < " \n "
< < " \t \t if (r2 < " < < vv < < " ) \n "
< < " \t \t { \n "
< < " \t \t real_t r = " < < weight < < " * sqrt( " < < vv < < " / r2 - 1); \n "
< < " \n "
< < " \t \t vOut.x = r * vIn.x; \n "
< < " \t \t vOut.y = r * vIn.y; \n "
< < " \t \t vOut.z = r * efTez * (real_t)(0.5); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < weight < < " * vIn.x; \n "
< < " \t \t vOut.y = " < < weight < < " * vIn.y; \n "
< < " \t \t vOut.z = " < < weight < < " * efTez * (real_t)(0.5); \n "
< < " \t \t } \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_Vv = SQR ( m_Weight ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Vv , prefix + " loonie_3D_vv " ) ) ; //Precalcs only, no params.
}
private :
T m_Vv ; //Precalcs only, no params.
} ;
/// <summary>
/// mcarpet.
/// </summary>
template < typename T >
class McarpetVariation : public ParametricVariation < T >
{
public :
McarpetVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " mcarpet " , eVariationId : : VAR_MCARPET , weight , true )
{
Init ( ) ;
}
PARVARCOPY ( McarpetVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T t = helper . m_PrecalcSumSquares * T ( 0.25 ) + 1 ;
T r = m_Weight / t ;
helper . Out . x = helper . In . x * r * m_X ;
helper . Out . y = helper . In . y * r * m_Y ;
helper . Out . x + = ( 1 - ( m_Twist * SQR ( helper . In . x ) ) + helper . In . y ) * m_Weight ; //The += is intentional.
helper . Out . y + = m_Tilt * helper . In . x * m_Weight ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string twist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string tilt = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t t = fma(precalcSumSquares, (real_t)(0.25), (real_t)(1.0)); \n "
< < " \t \t real_t r = " < < weight < < " / t; \n "
< < " \n "
< < " \t \t vOut.x = vIn.x * r * " < < x < < " ; \n "
< < " \t \t vOut.y = vIn.y * r * " < < y < < " ; \n "
< < " \t \t vOut.x += (1 - ( " < < twist < < " * SQR(vIn.x)) + vIn.y) * " < < weight < < " ; \n "
< < " \t \t vOut.y += " < < tilt < < " * vIn.x * " < < weight < < " ; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " mcarpet_x " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " mcarpet_y " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Twist , prefix + " mcarpet_twist " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Tilt , prefix + " mcarpet_tilt " ) ) ;
}
private :
T m_X ;
T m_Y ;
T m_Twist ;
T m_Tilt ;
} ;
/// <summary>
/// waves2_3D.
/// Original used a precalc for the input points, but it doesn't
/// work with Ember's design (and is also likely wrong), so it gets calculated on every iter
/// which is slightly slower, but more correct.
/// </summary>
template < typename T >
class Waves23DVariation : public ParametricVariation < T >
{
public :
Waves23DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " waves2_3D " , eVariationId : : VAR_WAVES23D , weight )
{
Init ( ) ;
}
PARVARCOPY ( Waves23DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T avgxy = ( helper . In . x + helper . In . y ) * T ( 0.5 ) ;
helper . Out . x = m_Weight * ( helper . In . x + m_Scale * std : : sin ( helper . In . y * m_Freq ) ) ;
helper . Out . y = m_Weight * ( helper . In . y + m_Scale * std : : sin ( helper . In . x * m_Freq ) ) ;
helper . Out . z = m_Weight * ( helper . In . z + m_Scale * std : : sin ( avgxy * m_Freq ) ) ; //Averages the XY to get Z.
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string freq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t avgxy = (vIn.x + vIn.y) * (real_t)(0.5); \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * fma( " < < scale < < " , sin(vIn.y * " < < freq < < " ), vIn.x); \n "
< < " \t \t vOut.y = " < < weight < < " * fma( " < < scale < < " , sin(vIn.x * " < < freq < < " ), vIn.y); \n "
< < " \t \t vOut.z = " < < weight < < " * fma( " < < scale < < " , sin(avgxy * " < < freq < < " ), vIn.z); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Freq , prefix + " waves2_3D_freq " , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scale , prefix + " waves2_3D_scale " , 1 ) ) ;
}
private :
T m_Freq ;
T m_Scale ;
} ;
/// <summary>
/// Pie3D.
/// </summary>
template < typename T >
class Pie3DVariation : public ParametricVariation < T >
{
public :
Pie3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " pie3D " , eVariationId : : VAR_PIE3D , weight )
{
Init ( ) ;
}
PARVARCOPY ( Pie3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int sl = int ( rand . Frand01 < T > ( ) * m_Slices + T ( 0.5 ) ) ;
T a = m_Rotation + M_2PI * ( sl + rand . Frand01 < T > ( ) * m_Thickness ) / m_Slices ;
T r = m_Weight * rand . Frand01 < T > ( ) ;
helper . Out . x = r * std : : cos ( a ) ;
helper . Out . y = r * std : : sin ( a ) ;
helper . Out . z = m_Weight * std : : sin ( r ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
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 \t int sl = (int)fma(MwcNext01(mwc), " < < slices < < " , (real_t)(0.5)); \n "
< < " \t \t real_t a = fma(M_2PI, fma(MwcNext01(mwc), " < < thickness < < " , (real_t)(sl)) / " < < slices < < " , " < < rotation < < " ); \n "
< < " \t \t real_t r = " < < weight < < " * MwcNext01(mwc); \n "
< < " \n "
< < " \t \t vOut.x = r * cos(a); \n "
< < " \t \t vOut.y = r * sin(a); \n "
< < " \t \t vOut.z = " < < weight < < " * sin(r); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Random ( QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
m_Params [ 0 ] . Set ( 10 * rand . Frand01 < T > ( ) ) ; //Slices.
m_Params [ 1 ] . Set ( M_2PI * rand . Frand11 < T > ( ) ) ; //Rotation.
m_Thickness = rand . Frand01 < T > ( ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Slices , prefix + " pie3D_slices " , 6 , eParamType : : INTEGER_NONZERO , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Rotation , prefix + " pie3D_rotation " , T ( 0.5 ) , eParamType : : REAL_CYCLIC , 0 , M_2PI ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Thickness , prefix + " pie3D_thickness " , T ( 0.5 ) , eParamType : : REAL , 0 , 1 ) ) ;
}
private :
T m_Slices ;
T m_Rotation ;
T m_Thickness ;
} ;
/// <summary>
/// popcorn2_3D.
/// </summary>
template < typename T >
class Popcorn23DVariation : public ParametricVariation < T >
{
public :
Popcorn23DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " popcorn2_3D " , eVariationId : : VAR_POPCORN23D , weight , false , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Popcorn23DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T otherZ , tempPZ = 0 ;
T tempTZ = helper . In . z = = 0 ? m_Vv * m_SinTanC * helper . m_PrecalcAtanyx : helper . In . z ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
otherZ = helper . In . z ;
else
otherZ = outPoint . m_Z ;
if ( otherZ = = 0 )
tempPZ = m_Vv * m_SinTanC * helper . m_PrecalcAtanyx ;
helper . Out . x = m_HalfWeight * ( helper . In . x + m_X * std : : sin ( SafeTan < T > ( m_C * helper . In . y ) ) ) ;
helper . Out . y = m_HalfWeight * ( helper . In . y + m_Y * std : : sin ( SafeTan < T > ( m_C * helper . In . x ) ) ) ;
helper . Out . z = tempPZ + m_Vv * ( m_Z * m_SinTanC * tempTZ ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
int i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string z = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string c = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string stc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hw = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string vv = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t otherZ, tempPZ = 0; \n "
< < " \t \t real_t tempTZ = vIn.z == 0 ? " < < vv < < " * " < < stc < < " * precalcAtanyx : vIn.z; \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
ss < < " \t \t otherZ = vIn.z; \n " ;
else
ss < < " \t \t otherZ = outPoint->m_Z; \n " ;
ss < < " \t \t if (otherZ == 0) \n "
< < " \t \t tempPZ = " < < vv < < " * " < < stc < < " * precalcAtanyx; \n "
< < " \n "
< < " \t \t vOut.x = " < < hw < < " * fma( " < < x < < " , sin(tan( " < < c < < " * vIn.y)), vIn.x); \n "
< < " \t \t vOut.y = " < < hw < < " * fma( " < < y < < " , sin(tan( " < < c < < " * vIn.x)), vIn.y); \n "
< < " \t \t vOut.z = fma( " < < vv < < " , ( " < < z < < " * " < < stc < < " * tempTZ), tempPZ); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_SinTanC = std : : sin ( SafeTan < T > ( m_C ) ) ;
m_HalfWeight = m_Weight * T ( 0.5 ) ;
if ( std : : abs ( m_Weight ) < = 1 )
m_Vv = std : : abs ( m_Weight ) * m_Weight ; //Sqr(m_Weight) value retaining sign.
else
m_Vv = m_Weight ;
}
virtual void Random ( QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
m_X = T ( 0.2 ) + rand . Frand01 < T > ( ) ;
m_Y = T ( 0.2 ) * rand . Frand01 < T > ( ) ;
m_Z = T ( 0.2 ) * rand . Frand01 < T > ( ) ;
m_C = 5 * rand . Frand01 < T > ( ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " popcorn2_3D_x " , T ( 0.1 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " popcorn2_3D_y " , T ( 0.1 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Z , prefix + " popcorn2_3D_z " , T ( 0.1 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_C , prefix + " popcorn2_3D_c " , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SinTanC , prefix + " popcorn2_3D_sintanc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HalfWeight , prefix + " popcorn2_3D_half_weight " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Vv , prefix + " popcorn2_3D_vv " ) ) ;
}
private :
T m_X ;
T m_Y ;
T m_Z ;
T m_C ;
T m_SinTanC ; //Precalcs.
T m_HalfWeight ;
T m_Vv ;
} ;
/// <summary>
/// sinusoidal3d.
/// </summary>
template < typename T >
class Sinusoidal3DVariation : public Variation < T >
{
public :
Sinusoidal3DVariation ( T weight = 1.0 ) : Variation < T > ( " sinusoidal3D " , eVariationId : : VAR_SINUSOIDAL3D , weight ) { }
VARCOPY ( Sinusoidal3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
helper . Out . x = m_Weight * std : : sin ( helper . In . x ) ;
helper . Out . y = m_Weight * std : : sin ( helper . In . y ) ;
helper . Out . z = m_Weight * ( std : : atan2 ( SQR ( helper . In . x ) , SQR ( helper . In . y ) ) * std : : cos ( helper . In . z ) ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss ;
string weight = WeightDefineString ( ) ;
ss < < " \t { \n "
< < " \t \t vOut.x = " < < weight < < " * sin(vIn.x); \n "
< < " \t \t vOut.y = " < < weight < < " * sin(vIn.y); \n "
< < " \t \t vOut.z = " < < weight < < " * (atan2(SQR(vIn.x), SQR(vIn.y)) * cos(vIn.z)); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
} ;
/// <summary>
/// scry_3D.
/// </summary>
template < typename T >
class Scry3DVariation : public ParametricVariation < T >
{
public :
Scry3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " scry_3D " , eVariationId : : VAR_SCRY3D , weight , true , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Scry3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T t = helper . m_PrecalcSumSquares + SQR ( helper . In . z ) ;
T r = 1 / Zeps ( std : : sqrt ( t ) * ( t + m_InvWeight ) ) ;
T z = helper . In . z = = 0 ? helper . m_PrecalcAtanyx : helper . In . z ;
helper . Out . x = helper . In . x * r ;
helper . Out . y = helper . In . y * r ;
helper . Out . z = z * r ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
int i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string invWeight = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t t = fma(vIn.z, vIn.z, precalcSumSquares); \n "
< < " \t \t real_t r = 1 / Zeps(sqrt(t) * (t + " < < invWeight < < " )); \n "
< < " \t \t real_t z = vIn.z == 0 ? precalcAtanyx : vIn.z; \n "
< < " \n "
< < " \t \t vOut.x = vIn.x * r; \n "
< < " \t \t vOut.y = vIn.y * r; \n "
< < " \t \t vOut.z = z * r; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_InvWeight = 1 / Zeps ( m_Weight ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_InvWeight , prefix + " scry_3D_inv_weight " ) ) ; //Precalcs only, no params.
}
private :
T m_InvWeight ; //Precalcs only, no params.
} ;
/// <summary>
/// shredlin.
/// </summary>
template < typename T >
class ShredlinVariation : public ParametricVariation < T >
{
public :
ShredlinVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " shredlin " , eVariationId : : VAR_SHRED_LIN , weight )
{
Init ( ) ;
}
PARVARCOPY ( ShredlinVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
const int xpos = helper . In . x < 0 ;
const int ypos = helper . In . y < 0 ;
const T xrng = helper . In . x / m_XDistance ;
const T yrng = helper . In . y / m_YDistance ;
helper . Out . x = m_Xw * ( ( xrng - int ( xrng ) ) * m_XWidth + int ( xrng ) + ( T ( 0.5 ) - xpos ) * m_1mX ) ;
helper . Out . y = m_Yw * ( ( yrng - int ( yrng ) ) * m_YWidth + int ( yrng ) + ( T ( 0.5 ) - ypos ) * m_1mY ) ;
helper . Out . z = m_Weight * helper . In . z ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string xdist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string xwidth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ydist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ywidth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string xw = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string yw = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string onemx = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string onemy = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t const int xpos = vIn.x < 0; \n "
< < " \t \t const int ypos = vIn.y < 0; \n "
< < " \t \t const real_t xrng = vIn.x / " < < xdist < < " ; \n "
< < " \t \t const real_t yrng = vIn.y / " < < ydist < < " ; \n "
< < " \n "
< < " \t \t vOut.x = " < < xw < < " * fma((xrng - (int)xrng), " < < xwidth < < " , (int)xrng + ((real_t)(0.5) - xpos) * " < < onemx < < " ); \n "
< < " \t \t vOut.y = " < < yw < < " * fma((yrng - (int)yrng), " < < ywidth < < " , (int)yrng + ((real_t)(0.5) - ypos) * " < < onemy < < " ); \n "
< < " \t \t vOut.z = " < < weight < < " * vIn.z; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_Xw = m_Weight * m_XDistance ;
m_Yw = m_Weight * m_YDistance ;
m_1mX = 1 - m_XWidth ;
m_1mY = 1 - m_YWidth ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_XDistance , prefix + " shredlin_xdistance " , 1 , eParamType : : REAL_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_XWidth , prefix + " shredlin_xwidth " , T ( 0.5 ) , eParamType : : REAL , - 1 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_YDistance , prefix + " shredlin_ydistance " , 1 , eParamType : : REAL_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_YWidth , prefix + " shredlin_ywidth " , T ( 0.5 ) , eParamType : : REAL , - 1 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Xw , prefix + " shredlin_xw " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Yw , prefix + " shredlin_yw " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_1mX , prefix + " shredlin_1mx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_1mY , prefix + " shredlin_1my " ) ) ;
}
private :
T m_XDistance ;
T m_XWidth ;
T m_YDistance ;
T m_YWidth ;
T m_Xw ; //Precalc.
T m_Yw ;
T m_1mX ;
T m_1mY ;
} ;
/// <summary>
/// splitbrdr.
/// </summary>
template < typename T >
class SplitBrdrVariation : public ParametricVariation < T >
{
public :
SplitBrdrVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " SplitBrdr " , eVariationId : : VAR_SPLIT_BRDR , weight , true )
{
Init ( ) ;
}
PARVARCOPY ( SplitBrdrVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T b = m_Weight / ( helper . m_PrecalcSumSquares * T ( 0.25 ) + 1 ) ;
T roundX = std : : rint ( helper . In . x ) ;
T roundY = std : : rint ( helper . In . y ) ;
T offsetX = helper . In . x - roundX ;
T offsetY = helper . In . y - roundY ;
helper . Out . x = helper . In . x * b ;
helper . Out . y = helper . In . y * b ;
if ( rand . Frand01 < T > ( ) > = T ( 0.75 ) )
{
helper . Out . x + = m_Weight * ( offsetX * T ( 0.5 ) + roundX ) ;
helper . Out . y + = m_Weight * ( offsetY * T ( 0.5 ) + roundY ) ;
}
else
{
if ( std : : abs ( offsetX ) > = std : : abs ( offsetY ) )
{
if ( offsetX > = 0 )
{
helper . Out . x + = m_Weight * ( offsetX * T ( 0.5 ) + roundX + m_X ) ;
helper . Out . y + = m_Weight * ( offsetY * T ( 0.5 ) + roundY + m_Y * offsetY / Zeps ( offsetX ) ) ;
}
else
{
helper . Out . x + = m_Weight * ( offsetX * T ( 0.5 ) + roundX - m_Y ) ;
helper . Out . y + = m_Weight * ( offsetY * T ( 0.5 ) + roundY - m_Y * offsetY / Zeps ( offsetX ) ) ;
}
}
else
{
if ( offsetY > = 0 )
{
helper . Out . y + = m_Weight * ( offsetY * T ( 0.5 ) + roundY + m_Y ) ;
helper . Out . x + = m_Weight * ( offsetX * T ( 0.5 ) + roundX + offsetX / Zeps ( offsetY ) * m_Y ) ;
}
else
{
helper . Out . y + = m_Weight * ( offsetY * T ( 0.5 ) + roundY - m_Y ) ;
helper . Out . x + = m_Weight * ( offsetX * T ( 0.5 ) + roundX - offsetX / Zeps ( offsetY ) * m_X ) ;
}
}
}
helper . Out . x + = helper . In . x * m_Px ;
helper . Out . y + = helper . In . y * m_Py ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string x = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string px = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string py = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t b = " < < weight < < " / fma(precalcSumSquares, (real_t)(0.25), (real_t)(1.0)); \n "
< < " \t \t real_t roundX = rint(vIn.x); \n "
< < " \t \t real_t roundY = rint(vIn.y); \n "
< < " \t \t real_t offsetX = vIn.x - roundX; \n "
< < " \t \t real_t offsetY = vIn.y - roundY; \n "
< < " \n "
< < " \t \t vOut.x = vIn.x * b; \n "
< < " \t \t vOut.y = vIn.y * b; \n "
< < " \n "
< < " \t \t if (MwcNext01(mwc) >= (real_t)(0.75)) \n "
< < " \t \t { \n "
< < " \t \t vOut.x += " < < weight < < " * fma(offsetX, (real_t)(0.5), roundX); \n "
< < " \t \t vOut.y += " < < weight < < " * fma(offsetY, (real_t)(0.5), roundY); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if (fabs(offsetX) >= fabs(offsetY)) \n "
< < " \t \t { \n "
< < " \t \t if (offsetX >= 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.x += " < < weight < < " * fma(offsetX, (real_t)(0.5), roundX + " < < x < < " ); \n "
< < " \t \t vOut.y += " < < weight < < " * fma(offsetY, (real_t)(0.5), fma( " < < y < < " , offsetY / Zeps(offsetX), roundY)); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x += " < < weight < < " * fma(offsetX, (real_t)(0.5), roundX - " < < y < < " ); \n "
< < " \t \t vOut.y += " < < weight < < " * fma(offsetY, (real_t)(0.5), roundY - " < < y < < " * offsetY / Zeps(offsetX)); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if (offsetY >= 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.y += " < < weight < < " * fma(offsetY, (real_t)(0.5), roundY + " < < y < < " ); \n "
< < " \t \t vOut.x += " < < weight < < " * fma(offsetX, (real_t)(0.5), roundX + offsetX / Zeps(offsetY) * " < < y < < " ); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.y += " < < weight < < " * fma(offsetY, (real_t)(0.5), roundY - " < < y < < " ); \n "
< < " \t \t vOut.x += " < < weight < < " * fma(offsetX, (real_t)(0.5), roundX - offsetX / Zeps(offsetY) * " < < x < < " ); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x += vIn.x * " < < px < < " ; \n "
< < " \t \t vOut.y += vIn.y * " < < py < < " ; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X , prefix + " SplitBrdr_x " , T ( 0.25 ) ) ) ; //Original used a prefix of splitb_, which is incompatible with Ember's design.
m_Params . push_back ( ParamWithName < T > ( & m_Y , prefix + " SplitBrdr_y " , T ( 0.25 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Px , prefix + " SplitBrdr_px " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Py , prefix + " SplitBrdr_py " ) ) ;
}
private :
T m_X ;
T m_Y ;
T m_Px ;
T m_Py ;
} ;
/// <summary>
/// wdisc.
/// </summary>
template < typename T >
class WdiscVariation : public Variation < T >
{
public :
WdiscVariation ( T weight = 1.0 ) : Variation < T > ( " wdisc " , eVariationId : : VAR_WDISC , weight , true , true , false , false , true ) { }
VARCOPY ( WdiscVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T a = T ( M_PI ) / ( helper . m_PrecalcSqrtSumSquares + 1 ) ;
T r = helper . m_PrecalcAtanyx * T ( M_1_PI ) ;
if ( r > 0 )
a = T ( M_PI ) - a ;
helper . Out . x = m_Weight * r * std : : cos ( a ) ;
helper . Out . y = m_Weight * r * std : : sin ( a ) ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss ;
string weight = WeightDefineString ( ) ;
ss < < " \t { \n "
< < " \t \t real_t a = MPI / (precalcSqrtSumSquares + 1); \n "
< < " \t \t real_t r = precalcAtanyx * M1PI; \n "
< < " \n "
< < " \t \t if (r > 0) \n "
< < " \t \t a = MPI - a; \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * r * cos(a); \n "
< < " \t \t vOut.y = " < < weight < < " * r * sin(a); \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
} ;
/// <summary>
/// falloff.
/// </summary>
template < typename T >
class FalloffVariation : public ParametricVariation < T >
{
public :
FalloffVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " falloff " , eVariationId : : VAR_FALLOFF , weight , false , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( FalloffVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
const T ax = rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) ;
const T ay = rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) ;
const T az = rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) ;
const T r = std : : sqrt ( Sqr ( helper . In . x - m_X0 ) + Sqr ( helper . In . y - m_Y0 ) + Sqr ( helper . In . z - m_Z0 ) ) ;
const T rc = ( ( m_Invert ! = 0 ? std : : max < T > ( 1 - r , 0 ) : std : : max < T > ( r , 0 ) ) - m_MinDist ) * m_InternalScatter ; //Original called a macro named min, which internally performed max.
const T rs = std : : max < T > ( rc , 0 ) ;
T sigma , phi , rad , sigmas , sigmac , phis , phic ;
T scale , denom ;
switch ( int ( m_Type ) )
{
case 0 : //Linear.
helper . Out . x = m_Weight * ( helper . In . x + m_MulX * ax * rs ) ;
helper . Out . y = m_Weight * ( helper . In . y + m_MulY * ay * rs ) ;
helper . Out . z = m_Weight * ( helper . In . z + m_MulZ * az * rs ) ;
break ;
case 1 : //Radial.
rad = r + m_MulX * ax * rs ;
phi = helper . m_PrecalcAtanyx + m_MulY * ay * rs ;
sigma = std : : asin ( r = = 0 ? 0 : helper . In . z / r ) + m_MulZ * az * rs ;
sigmas = std : : sin ( sigma ) * m_Weight ;
sigmac = std : : cos ( sigma ) * m_Weight ;
phis = std : : sin ( phi ) ;
phic = std : : cos ( phi ) ;
helper . Out . x = rad * sigmac * phic ;
helper . Out . y = rad * sigmac * phis ;
helper . Out . z = rad * sigmas ;
break ;
case 2 : //Box.
default :
scale = Clamp < T > ( rs , 0 , T ( 0.9 ) ) + T ( 0.1 ) ;
denom = 1 / scale ;
helper . Out . x = m_Weight * Lerp < T > ( helper . In . x , std : : floor ( helper . In . x * denom ) + scale * ax , m_MulX * rs ) + m_MulX * std : : pow ( ax , m_BoxPow ) * rs * denom ; //m_BoxPow should be an integer value held in T,
helper . Out . y = m_Weight * Lerp < T > ( helper . In . y , std : : floor ( helper . In . y * denom ) + scale * ay , m_MulY * rs ) + m_MulY * std : : pow ( ay , m_BoxPow ) * rs * denom ; //so std::abs() shouldn't be necessary.
helper . Out . z = m_Weight * Lerp < T > ( helper . In . z , std : : floor ( helper . In . z * denom ) + scale * az , m_MulZ * rs ) + m_MulZ * std : : pow ( az , m_BoxPow ) * rs * denom ;
break ;
}
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string scatter = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string minDist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulX = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulY = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string z0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invert = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string type = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string boxPow = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string internalScatter = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t const real_t ax = MwcNext0505(mwc); \n "
< < " \t \t const real_t ay = MwcNext0505(mwc); \n "
< < " \t \t const real_t az = MwcNext0505(mwc); \n "
< < " \t \t const real_t xmx = vIn.x - " < < x0 < < " ; \n "
< < " \t \t const real_t ymy = vIn.y - " < < y0 < < " ; \n "
< < " \t \t const real_t zmz = vIn.z - " < < z0 < < " ; \n "
< < " \t \t const real_t r = sqrt(fma(xmx, xmx, fma(ymy, ymy, SQR(zmz)))); \n "
< < " \t \t const real_t rc = (( " < < invert < < " != 0 ? max(1 - r, (real_t)(0.0)) : max(r, (real_t)(0.0))) - " < < minDist < < " ) * " < < internalScatter < < " ; \n "
< < " \t \t const real_t rs = max(rc, (real_t)(0.0)); \n "
< < " \n "
< < " \t \t real_t sigma, phi, rad, sigmas, sigmac, phis, phic; \n "
< < " \t \t real_t scale, denom; \n "
< < " \n "
< < " \t \t switch ((int) " < < type < < " ) \n "
< < " \t \t { \n "
< < " \t \t case 0: \n "
< < " \t \t vOut.x = " < < weight < < " * fma( " < < mulX < < " , ax * rs, vIn.x); \n "
< < " \t \t vOut.y = " < < weight < < " * fma( " < < mulY < < " , ay * rs, vIn.y); \n "
< < " \t \t vOut.z = " < < weight < < " * fma( " < < mulZ < < " , az * rs, vIn.z); \n "
< < " \t \t break; \n "
< < " \t \t case 1: \n "
< < " \t \t rad = fma( " < < mulX < < " , ax * rs, r); \n "
< < " \t \t phi = fma( " < < mulY < < " , ay * rs, precalcAtanyx); \n "
< < " \t \t sigma = fma( " < < mulZ < < " , az * rs, asin(r == 0 ? (real_t)(0.0) : vIn.z / r)); \n "
< < " \n "
< < " \t \t sigmas = sin(sigma) * " < < weight < < " ; \n "
< < " \t \t sigmac = cos(sigma) * " < < weight < < " ; \n "
< < " \t \t phis = sin(phi); \n "
< < " \t \t phic = cos(phi); \n "
< < " \n "
< < " \t \t vOut.x = rad * sigmac * phic; \n "
< < " \t \t vOut.y = rad * sigmac * phis; \n "
< < " \t \t vOut.z = rad * sigmas; \n "
< < " \t \t break; \n "
< < " \t \t case 2: \n "
< < " \t \t default: \n "
< < " \t \t scale = clamp(rs, (real_t)(0.0), (real_t)(0.9)) + (real_t)(0.1); \n "
< < " \t \t denom = 1 / scale; \n "
< < " \t \t vOut.x = fma( " < < weight < < " , Lerp(vIn.x, fma(scale, ax, floor(vIn.x * denom)), " < < mulX < < " * rs), " < < mulX < < " * pow(ax, " < < boxPow < < " ) * rs * denom); \n "
< < " \t \t vOut.y = fma( " < < weight < < " , Lerp(vIn.y, fma(scale, ay, floor(vIn.y * denom)), " < < mulY < < " * rs), " < < mulY < < " * pow(ay, " < < boxPow < < " ) * rs * denom); \n "
< < " \t \t vOut.z = fma( " < < weight < < " , Lerp(vIn.z, fma(scale, az, floor(vIn.z * denom)), " < < mulZ < < " * rs), " < < mulZ < < " * pow(az, " < < boxPow < < " ) * rs * denom); \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Lerp " } ;
}
virtual void Precalc ( ) override
{
m_InternalScatter = T ( 0.04 ) * m_Scatter ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scatter , prefix + " falloff_scatter " , 1 , eParamType : : REAL , EPS , TMAX ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MinDist , prefix + " falloff_mindist " , T ( 0.5 ) , eParamType : : REAL , 0 , TMAX ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulX , prefix + " falloff_mul_x " , 1 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulY , prefix + " falloff_mul_y " , 1 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulZ , prefix + " falloff_mul_z " , 0 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X0 , prefix + " falloff_x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y0 , prefix + " falloff_y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Z0 , prefix + " falloff_z0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Invert , prefix + " falloff_invert " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Type , prefix + " falloff_type " , 0 , eParamType : : INTEGER , 0 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_BoxPow , prefix + " falloff_boxpow " , 2 , eParamType : : INTEGER , 2 , 32 ) ) ; //Original defaulted this to 0 which directly contradicts the specified range of 2-32.
m_Params . push_back ( ParamWithName < T > ( true , & m_InternalScatter , prefix + " falloff_internal_scatter " ) ) ;
}
private :
T m_Scatter ;
T m_MinDist ;
T m_MulX ;
T m_MulY ;
T m_MulZ ;
T m_X0 ;
T m_Y0 ;
T m_Z0 ;
T m_Invert ;
T m_Type ;
T m_BoxPow ;
T m_InternalScatter ;
} ;
/// <summary>
/// falloff2.
/// </summary>
template < typename T >
class Falloff2Variation : public ParametricVariation < T >
{
public :
Falloff2Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " falloff2 " , eVariationId : : VAR_FALLOFF2 , weight , true , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Falloff2Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
const v4T random ( rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) ) ;
const T distA = std : : sqrt ( Sqr ( helper . In . x - m_X0 ) + Sqr ( helper . In . y - m_Y0 ) + Sqr ( helper . In . z - m_Z0 ) ) ;
const T distB = m_Invert ! = 0 ? std : : max < T > ( 1 - distA , 0 ) : std : : max < T > ( distA , 0 ) ; //Original called a macro named min, which internally performed max.
const T dist = std : : max < T > ( ( distB - m_MinDist ) * m_RMax , 0 ) ;
switch ( int ( m_Type ) )
{
case 0 : //Linear.
{
helper . Out . x = ( helper . In . x + m_MulX * random . x * dist ) * m_Weight ;
helper . Out . y = ( helper . In . y + m_MulY * random . y * dist ) * m_Weight ;
helper . Out . z = ( helper . In . z + m_MulZ * random . z * dist ) * m_Weight ;
}
break ;
case 1 : //Radial.
{
if ( helper . In . x = = 0 & & helper . In . y = = 0 & & helper . In . z = = 0 )
{
helper . Out . x = helper . In . x * m_Weight ;
helper . Out . y = helper . In . y * m_Weight ;
helper . Out . z = helper . In . z * m_Weight ;
return ;
}
else
{
const T rIn = Zeps ( std : : sqrt ( helper . m_PrecalcSumSquares + SQR ( helper . In . z ) ) ) ;
const T r = rIn + m_MulX * random . x * dist ;
const T phi = helper . m_PrecalcAtanyx + m_MulY * random . y * dist ;
const T sigma = std : : asin ( helper . In . z / rIn ) + m_MulZ * random . z * dist ;
const T sigmas = std : : sin ( sigma ) * m_Weight ;
const T sigmac = std : : cos ( sigma ) * m_Weight ;
const T phis = std : : sin ( phi ) ;
const T phic = std : : cos ( phi ) ;
helper . Out . x = r * sigmac * phic ;
helper . Out . y = r * sigmac * phis ;
helper . Out . z = r * sigmas ;
}
}
break ;
case 2 : //Gaussian.
default :
{
const T sigma = dist * random . y * M_2PI ;
const T phi = dist * random . z * T ( M_PI ) ;
const T rad = dist * random . x ;
const T sigmas = std : : sin ( sigma ) ;
const T sigmac = std : : cos ( sigma ) ;
const T phis = std : : sin ( phi ) ;
const T phic = std : : cos ( phi ) ;
helper . Out . x = ( helper . In . x + m_MulX * rad * sigmac * phic ) * m_Weight ;
helper . Out . y = ( helper . In . y + m_MulY * rad * sigmac * phis ) * m_Weight ;
helper . Out . z = ( helper . In . z + m_MulZ * rad * sigmas ) * m_Weight ;
}
break ;
}
outPoint . m_ColorX = std : : abs ( fmod ( outPoint . m_ColorX + m_MulC * random . w * dist , T ( 1 ) ) ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
int i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string scatter = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string minDist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulX = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulY = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulC = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string z0 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invert = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string type = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rMax = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t const real_t randx = MwcNext0505(mwc); \n "
< < " \t \t const real_t randy = MwcNext0505(mwc); \n "
< < " \t \t const real_t randz = MwcNext0505(mwc); \n "
< < " \t \t const real_t randc = MwcNext0505(mwc); \n "
< < " \t \t const real_t xmx = vIn.x - " < < x0 < < " ; \n "
< < " \t \t const real_t ymy = vIn.y - " < < y0 < < " ; \n "
< < " \t \t const real_t zmz = vIn.z - " < < z0 < < " ; \n "
< < " \t \t const real_t distA = sqrt(fma(xmx, xmx, fma(ymy, ymy, SQR(zmz)))); \n "
< < " \t \t const real_t distB = " < < invert < < " != 0 ? max(1 - distA, (real_t)(0.0)) : max(distA, (real_t)(0.0)); \n "
< < " \t \t const real_t dist = max((distB - " < < minDist < < " ) * " < < rMax < < " , (real_t)(0.0)); \n "
< < " \n "
< < " \t \t switch ((int) " < < type < < " ) \n "
< < " \t \t { \n "
< < " \t \t case 0: \n "
< < " \t \t vOut.x = fma( " < < mulX < < " , randx * dist, vIn.x) * " < < weight < < " ; \n "
< < " \t \t vOut.y = fma( " < < mulY < < " , randy * dist, vIn.y) * " < < weight < < " ; \n "
< < " \t \t vOut.z = fma( " < < mulZ < < " , randz * dist, vIn.z) * " < < weight < < " ; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma( " < < mulC < < " , randc * dist, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t break; \n "
< < " \t \t case 1: \n "
< < " \t \t if (vIn.x == 0 && vIn.y == 0 && vIn.z == 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x * " < < weight < < " ; \n "
< < " \t \t vOut.y = vIn.y * " < < weight < < " ; \n "
< < " \t \t vOut.z = vIn.z * " < < weight < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t rIn = Zeps(sqrt(fma(vIn.z, vIn.z, precalcSumSquares))); \n "
< < " \t \t real_t r = fma( " < < mulX < < " , randx * dist, rIn); \n "
< < " \t \t real_t phi = fma( " < < mulY < < " , randy * dist, precalcAtanyx); \n "
< < " \t \t real_t sigma = fma( " < < mulZ < < " , randz * dist, asin(vIn.z / rIn)); \n "
< < " \t \t real_t sigmas = sin(sigma) * " < < weight < < " ; \n "
< < " \t \t real_t sigmac = cos(sigma) * " < < weight < < " ; \n "
< < " \t \t real_t phis = sin(phi); \n "
< < " \t \t real_t phic = cos(phi); \n "
< < " \n "
< < " \t \t vOut.x = r * sigmac * phic; \n "
< < " \t \t vOut.y = r * sigmac * phis; \n "
< < " \t \t vOut.z = r * sigmas; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma( " < < mulC < < " , randc * dist, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t } \n "
< < " \t \t break; \n "
< < " \t \t case 2: \n "
< < " \t \t default: \n "
< < " \t \t { \n "
< < " \t \t real_t sigma = dist * randy * M_2PI; \n "
< < " \t \t real_t phi = dist * randz * MPI; \n "
< < " \t \t real_t rad = dist * randx; \n "
< < " \t \t real_t sigmas = sin(sigma); \n "
< < " \t \t real_t sigmac = cos(sigma); \n "
< < " \t \t real_t phis = sin(phi); \n "
< < " \t \t real_t phic = cos(phi); \n "
< < " \n "
< < " \t \t vOut.x = fma( " < < mulX < < " * rad, sigmac * phic, vIn.x) * " < < weight < < " ; \n "
< < " \t \t vOut.y = fma( " < < mulY < < " * rad, sigmac * phis, vIn.y) * " < < weight < < " ; \n "
< < " \t \t vOut.z = fma( " < < mulZ < < " * rad, sigmas, vIn.z) * " < < weight < < " ; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma( " < < mulC < < " , randc * dist, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
virtual void Precalc ( ) override
{
m_RMax = T ( 0.04 ) * m_Scatter ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scatter , prefix + " falloff2_scatter " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MinDist , prefix + " falloff2_mindist " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulX , prefix + " falloff2_mul_x " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulY , prefix + " falloff2_mul_y " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulZ , prefix + " falloff2_mul_z " , 0 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulC , prefix + " falloff2_mul_c " , 0 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_X0 , prefix + " falloff2_x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Y0 , prefix + " falloff2_y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Z0 , prefix + " falloff2_z0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Invert , prefix + " falloff2_invert " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Type , prefix + " falloff2_type " , 0 , eParamType : : INTEGER , 0 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RMax , prefix + " falloff2_rmax " ) ) ; //Precalc.
}
private :
T m_Scatter ;
T m_MinDist ;
T m_MulX ;
T m_MulY ;
T m_MulZ ;
T m_MulC ;
T m_X0 ;
T m_Y0 ;
T m_Z0 ;
T m_Invert ;
T m_Type ;
T m_RMax ; //Precalc.
} ;
/// <summary>
/// falloff3.
/// </summary>
template < typename T >
class Falloff3Variation : public ParametricVariation < T >
{
public :
Falloff3Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " falloff3 " , eVariationId : : VAR_FALLOFF3 , weight , true , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( Falloff3Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
const v4T random ( rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) , rand . Frand < T > ( T ( - 0.5 ) , T ( 0.5 ) ) ) ;
T radius ;
if ( m_BlurShape = = 0 ) //Circle.
radius = std : : sqrt ( Sqr ( helper . In . x - m_CenterX ) + Sqr ( helper . In . y - m_CenterY ) + Sqr ( helper . In . z - m_CenterZ ) ) ;
else //Square.
radius = std : : max ( std : : abs ( helper . In . x - m_CenterX ) , std : : max ( std : : abs ( helper . In . y - m_CenterY ) , ( std : : abs ( helper . In . z - m_CenterZ ) ) ) ) ; //Original called a macro named min, which internally performed max.
const T dist = std : : max < T > ( ( ( m_InvertDistance ! = 0 ? std : : max < T > ( 1 - radius , 0 ) : std : : max < T > ( radius , 0 ) ) - m_MinDistance ) * m_RMax , 0 ) ;
switch ( int ( m_BlurType ) )
{
case 0 : //Gaussian.
{
const T sigma = dist * random . y * M_2PI ;
const T phi = dist * random . z * T ( M_PI ) ;
const T rad = dist * random . x ;
const T sigmas = std : : sin ( sigma ) ;
const T sigmac = std : : cos ( sigma ) ;
const T phis = std : : sin ( phi ) ;
const T phic = std : : cos ( phi ) ;
helper . Out . x = ( helper . In . x + m_MulX * rad * sigmac * phic ) * m_Weight ;
helper . Out . y = ( helper . In . y + m_MulY * rad * sigmac * phis ) * m_Weight ;
helper . Out . z = ( helper . In . z + m_MulZ * rad * sigmas ) * m_Weight ;
outPoint . m_ColorX = std : : abs ( fmod ( outPoint . m_ColorX + m_MulC * random . w * dist , T ( 1 ) ) ) ;
}
break ;
case 1 : //Radial.
if ( helper . In . x = = 0 & & helper . In . y = = 0 & & helper . In . z = = 0 )
{
helper . Out . x = helper . In . x * m_Weight ;
helper . Out . y = helper . In . y * m_Weight ;
helper . Out . z = helper . In . z * m_Weight ;
return ;
}
else
{
const T rIn = std : : sqrt ( helper . m_PrecalcSumSquares + SQR ( helper . In . z ) ) ;
const T r = rIn + m_MulX * random . x * dist ;
const T phi = helper . m_PrecalcAtanyx + m_MulY * random . y * dist ;
const T sigma = std : : asin ( helper . In . z / rIn ) + m_MulZ * random . z * dist ;
const T sigmas = std : : sin ( sigma ) * m_Weight ;
const T sigmac = std : : cos ( sigma ) * m_Weight ;
const T phis = std : : sin ( phi ) ;
const T phic = std : : cos ( phi ) ;
helper . Out . x = r * sigmac * phic ;
helper . Out . y = r * sigmac * phis ;
helper . Out . z = r * sigmas ;
outPoint . m_ColorX = std : : abs ( fmod ( outPoint . m_ColorX + m_MulC * random . w * dist , T ( 1 ) ) ) ;
}
break ;
case 2 : //Log.
default :
{
const T coeff = m_RMax < = EPS ? dist : dist + m_Alpha * ( VarFuncs < T > : : LogMap ( dist ) - dist ) ;
helper . Out . x = ( helper . In . x + VarFuncs < T > : : LogMap ( m_MulX ) * VarFuncs < T > : : LogScale ( random . x ) * coeff ) * m_Weight ;
helper . Out . y = ( helper . In . y + VarFuncs < T > : : LogMap ( m_MulY ) * VarFuncs < T > : : LogScale ( random . y ) * coeff ) * m_Weight ;
helper . Out . z = ( helper . In . z + VarFuncs < T > : : LogMap ( m_MulZ ) * VarFuncs < T > : : LogScale ( random . z ) * coeff ) * m_Weight ;
outPoint . m_ColorX = std : : abs ( fmod ( outPoint . m_ColorX + VarFuncs < T > : : LogMap ( m_MulC ) * VarFuncs < T > : : LogScale ( random . w ) * coeff , T ( 1 ) ) ) ;
}
break ;
}
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
int i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string blurType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string blurShape = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string blurStrength = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string minDist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invertDist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulX = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulY = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mulC = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string centerX = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string centerY = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string centerZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string alpha = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rMax = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t const real_t randx = MwcNext0505(mwc); \n "
< < " \t \t const real_t randy = MwcNext0505(mwc); \n "
< < " \t \t const real_t randz = MwcNext0505(mwc); \n "
< < " \t \t const real_t randc = MwcNext0505(mwc); \n "
< < " \t \t const real_t xmx = vIn.x - " < < centerX < < " ; \n "
< < " \t \t const real_t ymy = vIn.y - " < < centerY < < " ; \n "
< < " \t \t const real_t zmz = vIn.z - " < < centerZ < < " ; \n "
< < " \t \t real_t radius; \n "
< < " \n "
< < " \t \t if ( " < < blurShape < < " == 0) \n "
< < " \t \t radius = sqrt(fma(xmx, xmx, fma(ymy, ymy, SQR(zmz)))); \n "
< < " \t \t else \n "
< < " \t \t radius = max(fabs(xmx), max(fabs(ymy), (fabs(zmz)))); \n "
< < " \n "
< < " \t \t const real_t dist = max((( " < < invertDist < < " != 0 ? max(1 - radius, (real_t)(0.0)) : max(radius, (real_t)(0.0))) - " < < minDist < < " ) * " < < rMax < < " , (real_t)(0.0)); \n "
< < " \n "
< < " \t \t switch ((int) " < < blurType < < " ) \n "
< < " \t \t { \n "
< < " \t \t case 0: \n "
< < " \t \t { \n "
< < " \t \t real_t sigma = dist * randy * M_2PI; \n "
< < " \t \t real_t phi = dist * randz * MPI; \n "
< < " \t \t real_t rad = dist * randx; \n "
< < " \t \t real_t sigmas = sin(sigma); \n "
< < " \t \t real_t sigmac = cos(sigma); \n "
< < " \t \t real_t phis = sin(phi); \n "
< < " \t \t real_t phic = cos(phi); \n "
< < " \n "
< < " \t \t vOut.x = fma( " < < mulX < < " * rad, sigmac * phic, vIn.x) * " < < weight < < " ; \n "
< < " \t \t vOut.y = fma( " < < mulY < < " * rad, sigmac * phis, vIn.y) * " < < weight < < " ; \n "
< < " \t \t vOut.z = fma( " < < mulZ < < " * rad, sigmas, vIn.z) * " < < weight < < " ; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma( " < < mulC < < " , randc * dist, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t } \n "
< < " \t \t break; \n "
< < " \t \t case 1: \n "
< < " \t \t if (vIn.x == 0 && vIn.y == 0 && vIn.z == 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x * " < < weight < < " ; \n "
< < " \t \t vOut.y = vIn.y * " < < weight < < " ; \n "
< < " \t \t vOut.z = vIn.z * " < < weight < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t rIn = Zeps(sqrt(fma(vIn.z, vIn.z, precalcSumSquares))); \n "
< < " \t \t real_t r = fma( " < < mulX < < " , randx * dist, rIn); \n "
< < " \t \t real_t phi = fma( " < < mulY < < " , randy * dist, precalcAtanyx); \n "
< < " \t \t real_t sigma = fma( " < < mulZ < < " , randz * dist, asin(vIn.z / rIn)); \n "
< < " \t \t real_t sigmas = sin(sigma) * " < < weight < < " ; \n "
< < " \t \t real_t sigmac = cos(sigma) * " < < weight < < " ; \n "
< < " \t \t real_t phis = sin(phi); \n "
< < " \t \t real_t phic = cos(phi); \n "
< < " \n "
< < " \t \t vOut.x = r * sigmac * phic; \n "
< < " \t \t vOut.y = r * sigmac * phis; \n "
< < " \t \t vOut.z = r * sigmas; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma( " < < mulC < < " , randc * dist, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t } \n "
< < " \t \t break; \n "
< < " \t \t case 2: \n "
< < " \t \t default: \n "
< < " \t \t { \n "
< < " \t \t real_t coeff = " < < rMax < < " <= EPS ? dist : fma( " < < alpha < < " , (LogMap(dist) - dist), dist); \n "
< < " \n "
< < " \t \t vOut.x = fma(LogMap( " < < mulX < < " ), LogScale(randx) * coeff, vIn.x) * " < < weight < < " ; \n "
< < " \t \t vOut.y = fma(LogMap( " < < mulY < < " ), LogScale(randy) * coeff, vIn.y) * " < < weight < < " ; \n "
< < " \t \t vOut.z = fma(LogMap( " < < mulZ < < " ), LogScale(randz) * coeff, vIn.z) * " < < weight < < " ; \n "
< < " \t \t outPoint->m_ColorX = fabs(fmod(fma(LogMap( " < < mulC < < " ), LogScale(randc) * coeff, outPoint->m_ColorX), (real_t)(1.0))); \n "
< < " \t \t } \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " SignNz " , " LogMap " , " LogScale " , " Zeps " } ;
}
virtual void Precalc ( ) override
{
m_RMax = T ( 0.04 ) * m_BlurStrength ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_BlurType , prefix + " falloff3_blur_type " , 0 , eParamType : : INTEGER , 0 , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_BlurShape , prefix + " falloff3_blur_shape " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_BlurStrength , prefix + " falloff3_blur_strength " , 1 , eParamType : : REAL , EPS , TMAX ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MinDistance , prefix + " falloff3_min_distance " , T ( 0.5 ) , eParamType : : REAL , 0 , TMAX ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_InvertDistance , prefix + " falloff3_invert_distance " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulX , prefix + " falloff3_mul_x " , 1 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulY , prefix + " falloff3_mul_y " , 1 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulZ , prefix + " falloff3_mul_z " , 0 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulC , prefix + " falloff3_mul_c " , 0 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CenterX , prefix + " falloff3_center_x " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CenterY , prefix + " falloff3_center_y " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CenterZ , prefix + " falloff3_center_z " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Alpha , prefix + " falloff3_alpha " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RMax , prefix + " falloff3_rmax " ) ) ; //Precalc.
}
private :
T m_BlurType ;
T m_BlurShape ;
T m_BlurStrength ;
T m_MinDistance ;
T m_InvertDistance ;
T m_MulX ;
T m_MulY ;
T m_MulZ ;
T m_MulC ;
T m_CenterX ;
T m_CenterY ;
T m_CenterZ ;
T m_Alpha ;
T m_RMax ; //Precalc.
} ;
/// <summary>
/// xtrb.
/// </summary>
template < typename T >
class XtrbVariation : public ParametricVariation < T >
{
public :
XtrbVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " xtrb " , eVariationId : : VAR_XTRB , weight )
{
Init ( ) ;
}
PARVARCOPY ( XtrbVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
intmax_t m , n ;
T alpha , beta , offsetAl , offsetBe , offsetGa , x , y ;
//Transfer to trilinear coordinates, normalized to real distances from triangle sides.
DirectTrilinear ( helper . In . x , helper . In . y , alpha , beta ) ;
m = Floor < T > ( alpha / m_S2a ) ;
offsetAl = alpha - m * m_S2a ;
n = Floor < T > ( beta / m_S2b ) ;
offsetBe = beta - n * m_S2b ;
offsetGa = m_S2c - m_Ac * offsetAl - m_Bc * offsetBe ;
if ( offsetGa > 0 )
{
Hex ( offsetAl , offsetBe , offsetGa , alpha , beta , rand ) ;
}
else
{
offsetAl = m_S2a - offsetAl ;
offsetBe = m_S2b - offsetBe ;
offsetGa = - offsetGa ;
Hex ( offsetAl , offsetBe , offsetGa , alpha , beta , rand ) ;
alpha = m_S2a - alpha ;
beta = m_S2b - beta ;
}
alpha + = m * m_S2a ;
beta + = n * m_S2b ;
InverseTrilinear ( alpha , beta , x , y , rand ) ;
helper . Out . x = m_Weight * x ;
helper . Out . y = m_Weight * y ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) < < " ] " ;
string index = ss2 . str ( ) ;
string weight = WeightDefineString ( ) ;
string power = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string radius = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string width = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dist = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string a = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string b = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string sinC = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cosC = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ha = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hb = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ab = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ac = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ba = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string bc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ca = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cb = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2a = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2b = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2c = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2ab = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2ac = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s2bc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string width1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string width2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string width3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string absN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cn = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int m, n; \n "
< < " \t \t real_t alpha, beta, offsetAl, offsetBe, offsetGa, x, y; \n "
< < " \n "
< < " \t \t { \n " //DirectTrilinear function extracted out here.
< < " \t \t alpha = vIn.y + " < < radius < < " ; \n "
< < " \t \t beta = fma(vIn.x, " < < sinC < < " , fma(-vIn.y, " < < cosC < < " , " < < radius < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t m = floor(alpha / " < < s2a < < " ); \n "
< < " \t \t offsetAl = alpha - m * " < < s2a < < " ; \n "
< < " \t \t n = floor(beta / " < < s2b < < " ); \n "
< < " \t \t offsetBe = beta - n * " < < s2b < < " ; \n "
< < " \t \t offsetGa = " < < s2c < < " + fma(- " < < ac < < " , offsetAl, - " < < bc < < " * offsetBe); \n "
< < " \n "
< < " \t \t if (offsetGa > 0) \n "
< < " \t \t { \n "
< < " \n "
< < " \t \t Hex(offsetAl, offsetBe, offsetGa, \n "
< < " \t \t " < < width < < " , \n "
< < " \t \t " < < ha < < " , \n "
< < " \t \t " < < hb < < " , \n "
< < " \t \t " < < hc < < " , \n "
< < " \t \t " < < ab < < " , \n "
< < " \t \t " < < ba < < " , \n "
< < " \t \t " < < bc < < " , \n "
< < " \t \t " < < ca < < " , \n "
< < " \t \t " < < cb < < " , \n "
< < " \t \t " < < s2a < < " , \n "
< < " \t \t " < < s2b < < " , \n "
< < " \t \t " < < s2ab < < " , \n "
< < " \t \t " < < s2ac < < " , \n "
< < " \t \t " < < s2bc < < " , \n "
< < " \t \t " < < width1 < < " , \n "
< < " \t \t " < < width2 < < " , \n "
< < " \t \t " < < width3 < < " , \n "
< < " \t \t &alpha, &beta, mwc); \n "
< < " \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t offsetAl = " < < s2a < < " - offsetAl; \n "
< < " \t \t offsetBe = " < < s2b < < " - offsetBe; \n "
< < " \t \t offsetGa = -offsetGa; \n "
< < " \n "
< < " \t \t Hex(offsetAl, offsetBe, offsetGa, \n "
< < " \t \t " < < width < < " , \n "
< < " \t \t " < < ha < < " , \n "
< < " \t \t " < < hb < < " , \n "
< < " \t \t " < < hc < < " , \n "
< < " \t \t " < < ab < < " , \n "
< < " \t \t " < < ba < < " , \n "
< < " \t \t " < < bc < < " , \n "
< < " \t \t " < < ca < < " , \n "
< < " \t \t " < < cb < < " , \n "
< < " \t \t " < < s2a < < " , \n "
< < " \t \t " < < s2b < < " , \n "
< < " \t \t " < < s2ab < < " , \n "
< < " \t \t " < < s2ac < < " , \n "
< < " \t \t " < < s2bc < < " , \n "
< < " \t \t " < < width1 < < " , \n "
< < " \t \t " < < width2 < < " , \n "
< < " \t \t " < < width3 < < " , \n "
< < " \t \t &alpha, &beta, mwc); \n "
< < " \n "
< < " \t \t alpha = " < < s2a < < " - alpha; \n "
< < " \t \t beta = " < < s2b < < " - beta; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t alpha += m * " < < s2a < < " ; \n "
< < " \t \t beta += n * " < < s2b < < " ; \n "
< < " \n "
< < " \t \t { \n " //InverseTrilinear function extracted out here.
< < " \t \t real_t inx = fma(alpha - " < < radius < < " , " < < cosC < < " , beta - " < < radius < < " ) / " < < sinC < < " ; \n "
< < " \t \t real_t iny = alpha - " < < radius < < " ; \n "
< < " \t \t real_t angle = fma(M_2PI, (real_t)MwcNextRange(mwc, (uint) " < < absN < < " ), atan2(iny, inx)) / " < < power < < " ; \n "
< < " \t \t real_t r = " < < weight < < " * pow(fma(inx, inx, SQR(iny)), " < < cn < < " ); \n "
< < " \n "
< < " \t \t x = r * cos(angle); \n "
< < " \t \t y = r * sin(angle); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * x; \n "
< < " \t \t vOut.y = " < < weight < < " * y; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" \n "
" void Hex(real_t al, real_t be, real_t ga, \n "
" real_t width, \n "
" real_t ha, \n "
" real_t hb, \n "
" real_t hc, \n "
" real_t ab, \n "
" real_t ba, \n "
" real_t bc, \n "
" real_t ca, \n "
" real_t cb, \n "
" real_t s2a, \n "
" real_t s2b, \n "
" real_t s2ab, \n "
" real_t s2ac, \n "
" real_t s2bc, \n "
" real_t width1, \n "
" real_t width2, \n "
" real_t width3, \n "
" real_t* al1, real_t* be1, uint2* mwc) \n "
" { \n "
" real_t ga1, de1, r = MwcNext01(mwc); \n "
" \n "
" if (be < al) \n "
" { \n "
" if (ga < be) \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" de1 = width * be; \n "
" ga1 = width * ga; \n "
" } \n "
" else \n "
" { \n "
" ga1 = fma(width1, ga, width2 * hc * ga / be); \n "
" de1 = fma(width1, be, width2 * s2ab * ((real_t)(3.0) - ga / be)); \n "
" } \n "
" \n "
" *al1 = s2a + fma(-ba, de1, - ca * ga1); \n "
" *be1 = de1; \n "
" } \n "
" else \n "
" { \n "
" if (ga < al) \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" ga1 = width * ga; \n "
" de1 = width * be; \n "
" } \n "
" else \n "
" { \n "
" de1 = fma(width1, be, width2 * hb * be / ga); \n "
" ga1 = fma(width1, ga, width2 * s2ac * ((real_t)(3.0) - be / ga)); \n "
" } \n "
" \n "
" *al1 = s2a + fma(-ba, de1, -ca * ga1); \n "
" *be1 = de1; \n "
" } \n "
" else \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" *al1 = width * al; \n "
" *be1 = width * be; \n "
" } \n "
" else \n "
" { \n "
" *be1 = fma(width1, be, width2 * hb * be / al); \n "
" *al1 = fma(width1, al, width2 * s2ac * ((real_t)(3.0) - be / al)); \n "
" } \n "
" } \n "
" } \n "
" } \n "
" else \n "
" { \n "
" if (ga < al) \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" de1 = width * al; \n "
" ga1 = width * ga; \n "
" } \n "
" else \n "
" { \n "
" ga1 = fma(width1, ga, width2 * hc * ga / al); \n "
" de1 = fma(width1, al, width2 * s2ab * ((real_t)(3.0) - ga / al)); \n "
" } \n "
" \n "
" *be1 = s2b + fma(-ab, de1, -cb * ga1); \n "
" *al1 = de1; \n "
" } \n "
" else \n "
" { \n "
" if (ga < be) \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" ga1 = width * ga; \n "
" de1 = width * al; \n "
" } \n "
" else \n "
" { \n "
" de1 = fma(width1, al, width2 * ha * al / ga); \n "
" ga1 = fma(width1, ga, width2 * s2bc * ((real_t)(3.0) - al / ga)); \n "
" } \n "
" \n "
" *be1 = s2b + fma(-ab, de1, -cb * ga1); \n "
" *al1 = de1; \n "
" } \n "
" else \n "
" { \n "
" if (r >= width3) \n "
" { \n "
" *be1 = width * be; \n "
" *al1 = width * al; \n "
" } \n "
" else \n "
" { \n "
" *al1 = fma(width1, al, width2 * ha * al / be); \n "
" *be1 = fma(width1, be, width2 * s2bc * ((real_t)(3.0) - al / be)); \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" \n "
;
}
virtual void Precalc ( ) override
{
T s2 , sinA2 , cosA2 , sinB2 , cosB2 , sinC2 , cosC2 ;
T br = T ( 0.047 ) + m_A ;
T cr = T ( 0.047 ) + m_B ;
T ar = T ( M_PI ) - br - cr ;
T temp = ar / 2 ;
sincos ( temp , & sinA2 , & cosA2 ) ;
temp = br / 2 ;
sincos ( temp , & sinB2 , & cosB2 ) ;
temp = cr / 2 ;
sincos ( temp , & sinC2 , & cosC2 ) ;
sincos ( cr , & m_SinC , & m_CosC ) ;
T a = m_Radius * ( sinC2 / cosC2 + sinB2 / cosB2 ) ;
T b = m_Radius * ( sinC2 / cosC2 + sinA2 / cosA2 ) ;
T c = m_Radius * ( sinB2 / cosB2 + sinA2 / cosA2 ) ;
m_Width1 = 1 - m_Width ;
m_Width2 = 2 * m_Width ;
m_Width3 = 1 - m_Width * m_Width ;
s2 = m_Radius * ( a + b + c ) ;
m_Ha = s2 / a / 6 ;
m_Hb = s2 / b / 6 ;
m_Hc = s2 / c / 6 ;
m_Ab = a / b ; // a div on b
m_Ac = a / c ;
m_Ba = b / a ;
m_Bc = b / c ;
m_Ca = c / a ;
m_Cb = c / b ;
m_S2a = 6 * m_Ha ;
m_S2b = 6 * m_Hb ;
m_S2c = 6 * m_Hc ;
m_S2bc = s2 / ( b + c ) / 6 ;
m_S2ab = s2 / ( a + b ) / 6 ;
m_S2ac = s2 / ( a + c ) / 6 ;
if ( m_Power = = 0 )
m_Power = 2 ;
m_AbsN = T ( int ( std : : abs ( m_Power ) ) ) ;
m_Cn = m_Dist / m_Power / 2 ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Power , prefix + " xtrb_power " , 2 , eParamType : : INTEGER_NONZERO ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Radius , prefix + " xtrb_radius " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Width , prefix + " xtrb_width " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dist , prefix + " xtrb_dist " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_A , prefix + " xtrb_a " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_B , prefix + " xtrb_b " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SinC , prefix + " xtrb_sinc " ) ) ; //Precalcs.
m_Params . push_back ( ParamWithName < T > ( true , & m_CosC , prefix + " xtrb_cosc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ha , prefix + " xtrb_ha " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Hb , prefix + " xtrb_hb " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Hc , prefix + " xtrb_hc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ab , prefix + " xtrb_ab " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ac , prefix + " xtrb_ac " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ba , prefix + " xtrb_ba " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Bc , prefix + " xtrb_bc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Ca , prefix + " xtrb_ca " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Cb , prefix + " xtrb_cb " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2a , prefix + " xtrb_s2a " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2b , prefix + " xtrb_s2b " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2c , prefix + " xtrb_s2c " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2ab , prefix + " xtrb_s2ab " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2ac , prefix + " xtrb_s2ac " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S2bc , prefix + " xtrb_s2bc " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Width1 , prefix + " xtrb_width1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Width2 , prefix + " xtrb_width2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Width3 , prefix + " xtrb_width3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsN , prefix + " xtrb_absn " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Cn , prefix + " xtrb_cn " ) ) ;
}
private :
inline void DirectTrilinear ( T x , T y , T & al , T & be )
{
al = y + m_Radius ;
be = x * m_SinC - y * m_CosC + m_Radius ;
}
inline void InverseTrilinear ( T al , T be , T & x , T & y , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand )
{
T inx = ( be - m_Radius + ( al - m_Radius ) * m_CosC ) / m_SinC ;
T iny = al - m_Radius ;
T angle = ( std : : atan2 ( iny , inx ) + M_2PI * ( rand . Rand ( size_t ( m_AbsN ) ) ) ) / m_Power ;
T r = m_Weight * std : : pow ( SQR ( inx ) + SQR ( iny ) , m_Cn ) ;
x = r * std : : cos ( angle ) ;
y = r * std : : sin ( angle ) ;
}
void Hex ( T al , T be , T ga , T & al1 , T & be1 , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand )
{
T ga1 , de1 , r = rand . Frand01 < T > ( ) ;
if ( be < al )
{
if ( ga < be )
{
if ( r > = m_Width3 )
{
de1 = m_Width * be ;
ga1 = m_Width * ga ;
}
else
{
ga1 = m_Width1 * ga + m_Width2 * m_Hc * ga / be ;
de1 = m_Width1 * be + m_Width2 * m_S2ab * ( 3 - ga / be ) ;
}
al1 = m_S2a - m_Ba * de1 - m_Ca * ga1 ;
be1 = de1 ;
}
else
{
if ( ga < al )
{
if ( r > = m_Width3 )
{
ga1 = m_Width * ga ;
de1 = m_Width * be ;
}
else
{
de1 = m_Width1 * be + m_Width2 * m_Hb * be / ga ;
ga1 = m_Width1 * ga + m_Width2 * m_S2ac * ( 3 - be / ga ) ;
}
al1 = m_S2a - m_Ba * de1 - m_Ca * ga1 ;
be1 = de1 ;
}
else
{
if ( r > = m_Width3 )
{
al1 = m_Width * al ;
be1 = m_Width * be ;
}
else
{
be1 = m_Width1 * be + m_Width2 * m_Hb * be / al ;
al1 = m_Width1 * al + m_Width2 * m_S2ac * ( 3 - be / al ) ;
}
}
}
}
else
{
if ( ga < al )
{
if ( r > = m_Width3 )
{
de1 = m_Width * al ;
ga1 = m_Width * ga ;
}
else
{
ga1 = m_Width1 * ga + m_Width2 * m_Hc * ga / al ;
de1 = m_Width1 * al + m_Width2 * m_S2ab * ( 3 - ga / al ) ;
}
be1 = m_S2b - m_Ab * de1 - m_Cb * ga1 ;
al1 = de1 ;
}
else
{
if ( ga < be )
{
if ( r > = m_Width3 )
{
ga1 = m_Width * ga ;
de1 = m_Width * al ;
}
else
{
de1 = m_Width1 * al + m_Width2 * m_Ha * al / ga ;
ga1 = m_Width1 * ga + m_Width2 * m_S2bc * ( 3 - al / ga ) ;
}
be1 = m_S2b - m_Ab * de1 - m_Cb * ga1 ;
al1 = de1 ;
}
else
{
if ( r > = m_Width3 )
{
be1 = m_Width * be ;
al1 = m_Width * al ;
}
else
{
al1 = m_Width1 * al + m_Width2 * m_Ha * al / be ;
be1 = m_Width1 * be + m_Width2 * m_S2bc * ( 3 - al / be ) ;
}
}
}
}
}
T m_Power ;
T m_Radius ;
T m_Width ;
T m_Dist ;
T m_A ;
T m_B ;
T m_SinC ; //Precalcs.
T m_CosC ;
T m_Ha ;
T m_Hb ;
T m_Hc ;
T m_Ab ;
T m_Ac ;
T m_Ba ;
T m_Bc ;
T m_Ca ;
T m_Cb ;
T m_S2a ;
T m_S2b ;
T m_S2c ;
T m_S2ab ;
T m_S2ac ;
T m_S2bc ;
T m_Width1 ;
T m_Width2 ;
T m_Width3 ;
T m_AbsN ;
T m_Cn ;
} ;
/// <summary>
/// hexaplay3D.
/// This uses state and the OpenCL version looks different and better than the CPU.
/// </summary>
template < typename T >
class Hexaplay3DVariation : public ParametricVariation < T >
{
public :
Hexaplay3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " hexaplay3D " , eVariationId : : VAR_HEXAPLAY3D , weight )
{
Init ( ) ;
}
PARVARCOPY ( Hexaplay3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
if ( m_FCycle > 5 )
{
m_FCycle = 0 ;
m_RSwtch = T ( rand . RandBit ( ) ) ; //Chooses 6 or 3 nodes.
}
if ( m_BCycle > 2 )
{
m_BCycle = 0 ;
m_RSwtch = T ( rand . RandBit ( ) ) ; //Chooses 6 or 3 nodes.
}
T tempx , tempy ;
T sumX , sumY ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
sumX = outPoint . m_X ;
sumY = outPoint . m_Y ;
outPoint . m_X = 0 ; //Only need to clear regular, pre and post will overwrite by default.
outPoint . m_Y = 0 ;
}
else
{
sumX = helper . In . x ;
sumY = helper . In . y ;
}
int posNeg = rand . RandBit ( ) ? - 1 : 1 ;
//Creating Z factors relative to the planes. These will be added, whereas x and y will be assigned.
//Original does += z *, so using z on the right side of = is intentional.
if ( m_MajPlane = = 2 )
//Boost is the separation distance between the two planes.
helper . Out . z = helper . In . z * T ( 0.5 ) * m_ZLift + ( posNeg * m_Boost ) ;
else
helper . Out . z = helper . In . z * T ( 0.5 ) * m_ZLift ;
//Work out the segments and hexagonal nodes.
if ( m_RSwtch ) //Occasion to build using 60 degree segments.
{
int loc = int ( m_FCycle ) ; //Sequential nodes selection.
tempx = m_Seg60 [ loc ] . x ;
tempy = m_Seg60 [ loc ] . y ;
m_FCycle + + ;
}
else //Occasion to build on 120 degree segments.
{
int loc = int ( m_BCycle ) ; //Sequential nodes selection.
tempx = m_Seg120 [ loc ] . x ;
tempy = m_Seg120 [ loc ] . y ;
m_BCycle + + ;
}
helper . Out . x = ( ( sumX + helper . In . x ) * m_HalfScale ) + ( m_Weight * tempx ) ;
helper . Out . y = ( ( sumY + helper . In . y ) * m_HalfScale ) + ( m_Weight * tempy ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string stateIndex = ss2 . str ( ) ;
string majp = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string zlift = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string majplane = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string boost = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string seg60xStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 6 ; //Precalc.
string seg60yStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 6 ;
string seg120xStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 3 ;
string seg120yStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 3 ;
string halfScale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rswtch = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ; //State.
string fcycle = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
string bcycle = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
ss < < " \t { \n "
< < " \t \t if ( " < < fcycle < < " > 5) \n "
< < " \t \t { \n "
< < " \t \t " < < fcycle < < " = 0; \n "
< < " \t \t " < < rswtch < < " = (real_t)(MwcNext(mwc) & 1); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < bcycle < < " > 2) \n "
< < " \t \t { \n "
< < " \t \t " < < bcycle < < " = 0; \n "
< < " \t \t " < < rswtch < < " = (real_t)(MwcNext(mwc) & 1); \n "
< < " \t \t } \n "
< < " \t \t \n "
< < " \t \t real_t tempx, tempy; \n "
< < " \t \t real_t sumX, sumY; \n \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
ss
< < " \t \t sumX = outPoint->m_X; \n "
< < " \t \t sumY = outPoint->m_Y; \n "
< < " \t \t outPoint->m_X = 0; \n "
< < " \t \t outPoint->m_Y = 0; \n " ;
}
else
{
ss
< < " \t \t sumX = vIn.x; \n "
< < " \t \t sumY = vIn.y; \n " ;
}
ss
< < " \n "
< < " \t \t int posNeg = (MwcNext(mwc) & 1) ? -1 : 1; \n "
< < " \n "
< < " \t \t if ( " < < majplane < < " == 2) \n "
< < " \t \t vOut.z = fma(vIn.z * (real_t)(0.5), " < < zlift < < " , (posNeg * " < < boost < < " )); \n "
< < " \t \t else \n "
< < " \t \t vOut.z = vIn.z * 0.5 * " < < zlift < < " ; \n "
< < " \n "
< < " \t \t if ( " < < rswtch < < " ) \n "
< < " \t \t { \n "
< < " \t \t int loc = (int) " < < fcycle < < " ; \n "
< < " \t \t tempx = parVars[ " < < seg60xStartIndex < < " + loc]; \n "
< < " \t \t tempy = parVars[ " < < seg60yStartIndex < < " + loc]; \n "
< < " \t \t " < < fcycle < < " = " < < fcycle < < " + 1; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t int loc = (int) " < < bcycle < < " ; \n "
< < " \t \t tempx = parVars[ " < < seg120xStartIndex < < " + loc]; \n "
< < " \t \t tempy = parVars[ " < < seg120yStartIndex < < " + loc]; \n "
< < " \t \t " < < bcycle < < " = " < < bcycle < < " + 1; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = fma(sumX + vIn.x, " < < halfScale < < " , " < < weight < < " * tempx); \n "
< < " \t \t vOut.y = fma(sumY + vIn.y, " < < halfScale < < " , " < < weight < < " * tempy); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void InitStateVars ( T * t , size_t & index ) override
{
t [ index + + ] = T ( QTIsaac < ISAAC_SIZE , ISAAC_INT > : : LockedRandBit ( ) ) ;
t [ index + + ] = 0 ;
t [ index + + ] = 0 ;
}
virtual void Precalc ( ) override
{
T hlift = std : : sin ( T ( M_PI ) / 3 ) ;
m_RSwtch = std : : trunc ( QTIsaac < ISAAC_SIZE , ISAAC_INT > : : LockedFrand01 < T > ( ) * 3 ) ; //Chooses 6 or 3 nodes.
m_FCycle = 0 ;
m_BCycle = 0 ;
T absmajp = std : : abs ( m_MajP ) ;
if ( absmajp < = 1 )
{
m_MajPlane = 1 ; //Want either 1 or 2.
}
else
{
m_MajPlane = 2 ;
m_Boost = ( absmajp - 1 ) * T ( 0.5 ) ; //Distance above and below XY plane.
}
m_Seg60 [ 0 ] . x = 1 ;
m_Seg60 [ 1 ] . x = T ( 0.5 ) ;
m_Seg60 [ 2 ] . x = T ( - 0.5 ) ;
m_Seg60 [ 3 ] . x = - 1 ;
m_Seg60 [ 4 ] . x = T ( - 0.5 ) ;
m_Seg60 [ 5 ] . x = T ( 0.5 ) ;
m_Seg60 [ 0 ] . y = 0 ;
m_Seg60 [ 1 ] . y = hlift ;
m_Seg60 [ 2 ] . y = hlift ;
m_Seg60 [ 3 ] . y = 0 ;
m_Seg60 [ 4 ] . y = - hlift ;
m_Seg60 [ 5 ] . y = - hlift ;
m_Seg120 [ 0 ] . x = 1 ;
m_Seg120 [ 1 ] . x = T ( - 0.5 ) ;
m_Seg120 [ 2 ] . x = T ( - 0.5 ) ;
m_Seg120 [ 0 ] . y = 0 ;
m_Seg120 [ 1 ] . y = hlift ;
m_Seg120 [ 2 ] . y = - hlift ;
m_HalfScale = m_Scale * T ( 0.5 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 25 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MajP , prefix + " hexaplay3D_majp " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scale , prefix + " hexaplay3D_scale " , T ( 0.25 ) , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ZLift , prefix + " hexaplay3D_zlift " , T ( 0.25 ) , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_MajPlane , prefix + " hexaplay3D_majplane " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_Boost , prefix + " hexaplay3D_boost " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 0 ] . x , prefix + " hexaplay3D_seg60x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 1 ] . x , prefix + " hexaplay3D_seg60x1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 2 ] . x , prefix + " hexaplay3D_seg60x2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 3 ] . x , prefix + " hexaplay3D_seg60x3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 4 ] . x , prefix + " hexaplay3D_seg60x4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 5 ] . x , prefix + " hexaplay3D_seg60x5 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 0 ] . y , prefix + " hexaplay3D_seg60y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 1 ] . y , prefix + " hexaplay3D_seg60y1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 2 ] . y , prefix + " hexaplay3D_seg60y2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 3 ] . y , prefix + " hexaplay3D_seg60y3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 4 ] . y , prefix + " hexaplay3D_seg60y4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 5 ] . y , prefix + " hexaplay3D_seg60y5 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 0 ] . x , prefix + " hexaplay3D_seg120x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 1 ] . x , prefix + " hexaplay3D_seg120x1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 2 ] . x , prefix + " hexaplay3D_seg120x2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 0 ] . y , prefix + " hexaplay3D_seg120y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 1 ] . y , prefix + " hexaplay3D_seg120y1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 2 ] . y , prefix + " hexaplay3D_seg120y2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HalfScale , prefix + " hexaplay3D_halfscale " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_RSwtch , prefix + " hexaplay3D_rswtch " ) ) ; //State.
m_Params . push_back ( ParamWithName < T > ( true , true , & m_FCycle , prefix + " hexaplay3D_fcycle " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_BCycle , prefix + " hexaplay3D_bcycle " ) ) ;
}
private :
T m_MajP ;
T m_Scale ;
T m_ZLift ;
T m_MajPlane ; //Precalc.
T m_Boost ;
v2T m_Seg60 [ 6 ] ;
v2T m_Seg120 [ 3 ] ;
T m_HalfScale ;
T m_RSwtch ; //State.
T m_FCycle ;
T m_BCycle ;
} ;
/// <summary>
/// hexnix3D.
/// This uses state and the OpenCL version looks different and better than the CPU.
/// It takes care of doing either a sum or product of the output variables internally,
/// rather than relying on the calling code of Xform::Apply() to do it.
/// This is because different paths do different things to helper.Out.z
/// </summary>
template < typename T >
class Hexnix3DVariation : public ParametricVariation < T >
{
public :
Hexnix3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " hexnix3D " , eVariationId : : VAR_HEXNIX3D , weight )
{
Init ( ) ;
}
PARVARCOPY ( Hexnix3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
if ( m_FCycle > 5 )
{
m_FCycle = 0 ;
m_RSwtch = T ( rand . RandBit ( ) ) ; //Chooses 6 or 3 nodes.
}
if ( m_BCycle > 2 )
{
m_BCycle = 0 ;
m_RSwtch = T ( rand . RandBit ( ) ) ; //Chooses 6 or 3 nodes.
}
T smRotxFP = 0 ;
T smRotyFP = 0 ;
T smRotxFT = 0 ;
T smRotyFT = 0 ;
T sumX , sumY , sumZ ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
sumX = outPoint . m_X ;
sumY = outPoint . m_Y ;
sumZ = outPoint . m_Z ;
outPoint . m_X = 0 ;
outPoint . m_Y = 0 ; //Z is optionally cleared and assigned to below.
}
else
{
sumX = helper . In . x ;
sumY = helper . In . y ;
sumZ = helper . In . z ;
}
int posNeg = rand . RandBit ( ) ? - 1 : 1 ;
T scale3 ;
T tempx , tempy ;
if ( m_MajPlane = = 0 )
{
helper . Out . z = m_Smooth * helper . In . z * m_Scale * m_ZLift ;
}
else if ( m_MajPlane = = 1 & & m_MajP < 0 )
{
if ( posNeg < 0 )
helper . Out . z = - 2 * ( sumZ * m_GentleZ ) ;
}
else if ( m_MajPlane = = 2 & & m_MajP < 0 )
{
if ( posNeg > 0 )
{
helper . Out . z = ( m_Smooth * ( helper . In . z * m_Scale * m_ZLift + m_Boost ) ) ;
}
else //For this case when reg, assign and zero out. For all others, sum as usual.
{
helper . Out . z = ( sumZ - ( 2 * m_Smooth * sumZ ) ) + ( m_Smooth * posNeg * ( helper . In . z * m_Scale * m_ZLift + m_Boost ) ) ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
outPoint . m_Z = 0 ;
}
}
else
helper . Out . z = m_Smooth * ( helper . In . z * m_Scale * m_ZLift + ( posNeg * m_Boost ) ) ;
if ( m_RSwtch )
{
auto loc = rand . Rand ( 6 ) ;
tempx = m_Seg60 [ loc ] . x ;
tempy = m_Seg60 [ loc ] . y ;
scale3 = 1 ;
m_FCycle + + ;
}
else
{
auto loc = rand . Rand ( 3 ) ;
tempx = m_Seg120 [ loc ] . x ;
tempy = m_Seg120 [ loc ] . y ;
scale3 = m_3side ;
m_BCycle + + ;
}
smRotxFP = ( m_Smooth * m_Scale * sumX * tempx ) - ( m_Smooth * m_Scale * sumY * tempy ) ;
smRotyFP = ( m_Smooth * m_Scale * sumY * tempx ) + ( m_Smooth * m_Scale * sumX * tempy ) ;
smRotxFT = ( helper . In . x * m_Smooth * m_Scale * tempx ) - ( helper . In . y * m_Smooth * m_Scale * tempy ) ;
smRotyFT = ( helper . In . y * m_Smooth * m_Scale * tempx ) + ( helper . In . x * m_Smooth * m_Scale * tempy ) ;
helper . Out . x = sumX * ( 1 - m_Smooth ) + smRotxFP + smRotxFT + m_Smooth * m_Weight * scale3 * tempx ;
helper . Out . y = sumY * ( 1 - m_Smooth ) + smRotyFP + smRotyFT + m_Smooth * m_Weight * scale3 * tempy ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string stateIndex = ss2 . str ( ) ;
string majp = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string zlift = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string side3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string smooth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc.
string majplane = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string boost = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string gentlez = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string seg60xStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 6 ;
string seg60yStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 6 ;
string seg120xStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 3 ;
string seg120yStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 3 ;
string rswtch = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ; //State.
string fcycle = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
string bcycle = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
ss < < " \t { \n "
< < " \t \t if ( " < < fcycle < < " > 5) \n "
< < " \t \t { \n "
< < " \t \t " < < fcycle < < " = 0; \n "
< < " \t \t " < < rswtch < < " = (real_t)(MwcNext(mwc) & 1); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < bcycle < < " > 2) \n "
< < " \t \t { \n "
< < " \t \t " < < bcycle < < " = 0; \n "
< < " \t \t " < < rswtch < < " = (real_t)(MwcNext(mwc) & 1); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t real_t scale = " < < scale < < " ; \n " //This is an optimal blend of memory accesses vs. caching to local variables which seems to work best.
< < " \t \t real_t smooth = " < < smooth < < " ; \n "
< < " \t \t real_t smRotxFP = 0; \n "
< < " \t \t real_t smRotyFP = 0; \n "
< < " \t \t real_t smRotxFT = 0; \n "
< < " \t \t real_t smRotyFT = 0; \n "
< < " \t \t real_t sumX, sumY, sumZ; \n \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
ss
< < " \t \t sumX = outPoint->m_X; \n "
< < " \t \t sumY = outPoint->m_Y; \n "
< < " \t \t sumZ = outPoint->m_Z; \n "
< < " \t \t outPoint->m_X = 0; \n "
< < " \t \t outPoint->m_Y = 0; \n " ;
}
else
{
ss
< < " \t \t sumX = vIn.x; \n "
< < " \t \t sumY = vIn.y; \n "
< < " \t \t sumZ = vIn.z; \n " ;
}
ss
< < " \n "
< < " \t \t int posNeg = (MwcNext(mwc) & 1) ? -1 : 1; \n "
< < " \t \t real_t scale3; \n "
< < " \t \t real_t tempx, tempy; \n "
< < " \n "
< < " \t \t if ( " < < majplane < < " == 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.z = smooth * vIn.z * scale * " < < zlift < < " ; \n "
< < " \t \t } \n "
< < " \t \t else if ( " < < majplane < < " == 1 && " < < majp < < " < 0) \n "
< < " \t \t { \n "
< < " \t \t if (posNeg < 0) \n "
< < " \t \t vOut.z = -2 * (sumZ * " < < gentlez < < " ); \n "
< < " \t \t } \n "
< < " \t \t else if ( " < < majplane < < " == 2 && " < < majp < < " < 0) \n "
< < " \t \t { \n "
< < " \t \t if (posNeg > 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.z = (smooth * fma(vIn.z * scale, " < < zlift < < " , " < < boost < < " )); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.z = fma(smooth * posNeg, fma(vIn.z * scale, " < < zlift < < " , " < < boost < < " ), sumZ - ((real_t)(2.0) * smooth * sumZ)); \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
ss < < " \t \t outPoint->m_Z = 0; \n " ;
ss
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.z = smooth * fma(vIn.z * scale, " < < zlift < < " , (posNeg * " < < boost < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < rswtch < < " ) \n "
< < " \t \t { \n "
< < " \t \t uint loc = MwcNextRange(mwc, 6u); \n "
< < " \t \t tempx = parVars[ " < < seg60xStartIndex < < " + loc]; \n "
< < " \t \t tempy = parVars[ " < < seg60yStartIndex < < " + loc]; \n "
< < " \t \t scale3 = 1; \n "
< < " \t \t " < < fcycle < < " = " < < fcycle < < " + 1; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t uint loc = MwcNextRange(mwc, 3u); \n "
< < " \t \t tempx = parVars[ " < < seg120xStartIndex < < " + loc]; \n "
< < " \t \t tempy = parVars[ " < < seg120yStartIndex < < " + loc]; \n "
< < " \t \t scale3 = " < < side3 < < " ; \n "
< < " \t \t " < < bcycle < < " = " < < bcycle < < " + 1; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t smRotxFP = fma(smooth * scale, sumX * tempx, -(smooth * scale * sumY * tempy)); \n "
< < " \t \t smRotyFP = fma(smooth * scale, sumY * tempx, (smooth * scale * sumX * tempy)); \n "
< < " \t \t smRotxFT = fma(vIn.x * smooth, scale * tempx, -(vIn.y * smooth * scale * tempy)); \n "
< < " \t \t smRotyFT = fma(vIn.y * smooth, scale * tempx, (vIn.x * smooth * scale * tempy)); \n "
< < " \t \t vOut.x = fma(sumX, (1 - smooth), fma(smooth * " < < weight < < " , scale3 * tempx, smRotxFP + smRotxFT)); \n "
< < " \t \t vOut.y = fma(sumY, (1 - smooth), fma(smooth * " < < weight < < " , scale3 * tempy, smRotyFP + smRotyFT)); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void InitStateVars ( T * t , size_t & index ) override
{
t [ index + + ] = T ( QTIsaac < ISAAC_SIZE , ISAAC_INT > : : LockedRandBit ( ) ) ;
t [ index + + ] = 0 ;
t [ index + + ] = 0 ;
}
virtual void Precalc ( ) override
{
T hlift = std : : sin ( T ( M_PI ) / 3 ) ;
m_RSwtch = T ( QTIsaac < ISAAC_SIZE , ISAAC_INT > : : LockedRandBit ( ) ) ; // QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(4);// //std::trunc(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedFrand01<T>() * 3);//Chooses 6 or 3 nodes.
m_FCycle = 0 ;
m_BCycle = 0 ;
auto absmajp = std : : abs ( m_MajP ) ;
if ( absmajp < = 1 )
{
m_MajPlane = 0 ;
m_Boost = 0 ;
}
else if ( absmajp > 1 & & absmajp < 2 )
{
m_MajPlane = 1 ;
m_Boost = 0 ;
}
else
{
m_MajPlane = 2 ;
m_Boost = ( absmajp - 2 ) * T ( 0.5 ) ;
}
if ( m_MajPlane = = 1 & & m_MajP < 0 )
{
if ( m_MajP < - 1 & & m_MajP > = - 2 )
m_GentleZ = absmajp - 1 ;
else
m_GentleZ = 1 ;
}
else
m_GentleZ = 0 ;
if ( std : : abs ( m_Weight ) < = T ( 0.5 ) )
m_Smooth = m_Weight * 2 ;
else
m_Smooth = 1 ;
m_Seg60 [ 0 ] . x = 1 ;
m_Seg60 [ 1 ] . x = T ( 0.5 ) ;
m_Seg60 [ 2 ] . x = T ( - 0.5 ) ;
m_Seg60 [ 3 ] . x = - 1 ;
m_Seg60 [ 4 ] . x = T ( - 0.5 ) ;
m_Seg60 [ 5 ] . x = T ( 0.5 ) ;
m_Seg60 [ 0 ] . y = 0 ;
m_Seg60 [ 1 ] . y = - hlift ;
m_Seg60 [ 2 ] . y = - hlift ;
m_Seg60 [ 3 ] . y = 0 ;
m_Seg60 [ 4 ] . y = hlift ;
m_Seg60 [ 5 ] . y = hlift ;
m_Seg120 [ 0 ] . x = 0 ;
m_Seg120 [ 1 ] . x = std : : cos ( 7 * T ( M_PI ) / 6 ) ;
m_Seg120 [ 2 ] . x = std : : cos ( 11 * T ( M_PI ) / 6 ) ;
m_Seg120 [ 0 ] . y = - 1 ;
m_Seg120 [ 1 ] . y = T ( 0.5 ) ;
m_Seg120 [ 2 ] . y = T ( 0.5 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 25 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MajP , prefix + " hexnix3D_majp " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scale , prefix + " hexnix3D_scale " , T ( 0.25 ) , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ZLift , prefix + " hexnix3D_zlift " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_3side , prefix + " hexnix3D_3side " , T ( 0.667 ) , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Smooth , prefix + " hexnix3D_smooth " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_MajPlane , prefix + " hexnix3D_majplane " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Boost , prefix + " hexnix3D_boost " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_GentleZ , prefix + " hexnix3D_gentlez " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 0 ] . x , prefix + " hexnix3D_seg60x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 1 ] . x , prefix + " hexnix3D_seg60x1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 2 ] . x , prefix + " hexnix3D_seg60x2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 3 ] . x , prefix + " hexnix3D_seg60x3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 4 ] . x , prefix + " hexnix3D_seg60x4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 5 ] . x , prefix + " hexnix3D_seg60x5 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 0 ] . y , prefix + " hexnix3D_seg60y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 1 ] . y , prefix + " hexnix3D_seg60y1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 2 ] . y , prefix + " hexnix3D_seg60y2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 3 ] . y , prefix + " hexnix3D_seg60y3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 4 ] . y , prefix + " hexnix3D_seg60y4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg60 [ 5 ] . y , prefix + " hexnix3D_seg60y5 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 0 ] . x , prefix + " hexnix3D_seg120x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 1 ] . x , prefix + " hexnix3D_seg120x1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 2 ] . x , prefix + " hexnix3D_seg120x2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 0 ] . y , prefix + " hexnix3D_seg120y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 1 ] . y , prefix + " hexnix3D_seg120y1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Seg120 [ 2 ] . y , prefix + " hexnix3D_seg120y2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_RSwtch , prefix + " hexnix3D_rswtch " ) ) ; //State.
m_Params . push_back ( ParamWithName < T > ( true , true , & m_FCycle , prefix + " hexnix3D_fcycle " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_BCycle , prefix + " hexnix3D_bcycle " ) ) ;
}
private :
T m_MajP ;
T m_Scale ;
T m_ZLift ;
T m_3side ;
T m_Smooth ; //Precalc.
T m_MajPlane ;
T m_Boost ;
T m_GentleZ ;
v2T m_Seg60 [ 6 ] ;
v2T m_Seg120 [ 3 ] ;
T m_RSwtch ; //State.
T m_FCycle ;
T m_BCycle ;
} ;
/// <summary>
/// hexcrop.
/// </summary>
template < typename T >
class HexcropVariation : public ParametricVariation < T >
{
public :
HexcropVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " hexcrop " , eVariationId : : VAR_HEXCROP , weight )
{
Init ( ) ;
}
PARVARCOPY ( HexcropVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
v2T i ;
int c = 0 , n = - 1 , j = 5 ;
i . x = helper . In . x + m_CenterX ;
i . y = helper . In . y + m_CenterY ;
while ( + + n < 6 )
{
if ( ( m_P [ n ] . y < = i . y & & i . y < m_P [ j ] . y ) | | ( m_P [ j ] . y < = i . y & & i . y < m_P [ n ] . y ) )
if ( i . x < ( m_P [ j ] . x - m_P [ n ] . x ) * ( i . y - m_P [ n ] . y ) / Zeps ( m_P [ j ] . y - m_P [ n ] . y ) + m_P [ n ] . x )
c ^ = 1 ;
j = n ;
}
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
helper . Out . x = c ! = 0 ? outPoint . m_X + i . x * m_Weight : m_Dropoff ;
helper . Out . y = c ! = 0 ? outPoint . m_Y + i . y * m_Weight : m_Dropoff ;
outPoint . m_X = 0 ;
outPoint . m_Y = 0 ;
}
else
{
helper . Out . x = c ! = 0 ? i . x * m_Weight : m_Dropoff ;
helper . Out . y = c ! = 0 ? i . y * m_Weight : m_Dropoff ;
}
helper . Out . z = m_Weight * helper . In . z ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string stateIndex = ss2 . str ( ) ;
string scalex = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scaley = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string centerx = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string centery = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string dropoff = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string pxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 6 ; //Precalc.
string pyStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ;
ss < < " \t { \n "
< < " \t \t real2 i; \n "
< < " \t \t int c = 0, n = -1, j = 5; \n "
< < " \n "
< < " \t \t i.x = vIn.x + " < < centerx < < " ; \n "
< < " \t \t i.y = vIn.y + " < < centery < < " ; \n "
< < " \n "
< < " \t \t while (++n < 6) \n "
< < " \t \t { \n "
< < " \t \t int xjoff = " < < pxStartIndex < < " + j; \n "
< < " \t \t int xnoff = " < < pxStartIndex < < " + n; \n "
< < " \t \t int yjoff = " < < pyStartIndex < < " + j; \n "
< < " \t \t int ynoff = " < < pyStartIndex < < " + n; \n "
< < " \n "
< < " \t \t if ((parVars[ynoff] <= i.y && i.y < parVars[yjoff]) || (parVars[yjoff] <= i.y && i.y < parVars[ynoff])) \n "
< < " \t \t if (i.x < (parVars[xjoff] - parVars[xnoff]) * (i.y - parVars[ynoff]) / Zeps(parVars[yjoff] - parVars[ynoff]) + parVars[xnoff]) \n "
< < " \t \t c ^= 1; \n "
< < " \n "
< < " \t \t j = n; \n "
< < " \t \t } \n "
< < " \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
ss
< < " \t \t vOut.x = c != 0 ? fma(i.x, " < < weight < < " , outPoint->m_X) : " < < dropoff < < " ; \n "
< < " \t \t vOut.y = c != 0 ? fma(i.y, " < < weight < < " , outPoint->m_Y) : " < < dropoff < < " ; \n "
< < " \t \t outPoint->m_X = 0; \n "
< < " \t \t outPoint->m_Y = 0; \n " ;
}
else
{
ss
< < " \t \t vOut.x = c != 0 ? i.x * " < < weight < < " : " < < dropoff < < " ; \n "
< < " \t \t vOut.y = c != 0 ? i.y * " < < weight < < " : " < < dropoff < < " ; \n " ;
}
ss
< < " \t \t vOut.z = " < < weight < < " * vIn.z; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_P [ 0 ] . x = T ( - 0.5000000000000000000000000000000 ) * m_ScaleX ;
m_P [ 0 ] . y = T ( 1.0606601717798212866012665431573 ) * m_ScaleY ;
m_P [ 1 ] . x = T ( 0.5000000000000000000000000000000 ) * m_ScaleX ;
m_P [ 1 ] . y = T ( 1.0606601717798212866012665431573 ) * m_ScaleY ;
m_P [ 2 ] . x = T ( 1.4142135623730950488016887242097 ) * m_ScaleX ;
m_P [ 2 ] . y = T ( 0.0000000000000000000000000000000 ) * m_ScaleY ;
m_P [ 3 ] . x = T ( 0.5000000000000000000000000000000 ) * m_ScaleX ;
m_P [ 3 ] . y = T ( - 1.0606601717798212866012665431573 ) * m_ScaleY ;
m_P [ 4 ] . x = T ( - 0.5000000000000000000000000000000 ) * m_ScaleX ;
m_P [ 4 ] . y = T ( - 1.0606601717798212866012665431573 ) * m_ScaleY ;
m_P [ 5 ] . x = T ( - 1.4142135623730950488016887242097 ) * m_ScaleX ;
m_P [ 5 ] . y = T ( 0.0000000000000000000000000000000 ) * m_ScaleY ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 17 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ScaleX , prefix + " hexcrop_scale_x " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ScaleY , prefix + " hexcrop_scale_y " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CenterX , prefix + " hexcrop_center_x " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CenterY , prefix + " hexcrop_center_y " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Dropoff , prefix + " hexcrop_dropoff " , T ( 1E10 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 0 ] . x , prefix + " hexcrop_px0 " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 1 ] . x , prefix + " hexcrop_px1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 2 ] . x , prefix + " hexcrop_px2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 3 ] . x , prefix + " hexcrop_px3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 4 ] . x , prefix + " hexcrop_px4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 5 ] . x , prefix + " hexcrop_px5 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 0 ] . y , prefix + " hexcrop_py0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 1 ] . y , prefix + " hexcrop_py1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 2 ] . y , prefix + " hexcrop_py2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 3 ] . y , prefix + " hexcrop_py3 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 4 ] . y , prefix + " hexcrop_py4 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_P [ 5 ] . y , prefix + " hexcrop_py5 " ) ) ;
}
private :
T m_ScaleX ;
T m_ScaleY ;
T m_CenterX ;
T m_CenterY ;
T m_Dropoff ;
v2T m_P [ 6 ] ; //Precalc.
} ;
MAKEPREPOSTPARVAR ( Bubble2 , bubble2 , BUBBLE2 )
MAKEPREPOSTPARVAR ( CircleLinear , CircleLinear , CIRCLELINEAR )
MAKEPREPOSTPARVARASSIGN ( CircleRand , CircleRand , CIRCLERAND , eVariationAssignType : : ASSIGNTYPE_SUM )
MAKEPREPOSTPARVAR ( CircleTrans1 , CircleTrans1 , CIRCLETRANS1 )
MAKEPREPOSTPARVAR ( Cubic3D , cubic3D , CUBIC3D )
MAKEPREPOSTPARVAR ( CubicLattice3D , cubicLattice_3D , CUBIC_LATTICE3D )
MAKEPREPOSTVAR ( Foci3D , foci_3D , FOCI3D )
MAKEPREPOSTPARVAR ( FociP , foci_p , FOCI_P )
MAKEPREPOSTPARVAR ( Ho , ho , HO )
MAKEPREPOSTPARVAR ( Julia3Dq , julia3Dq , JULIA3DQ )
MAKEPREPOSTPARVARASSIGN ( Line , line , LINE , eVariationAssignType : : ASSIGNTYPE_SUM )
MAKEPREPOSTPARVAR ( Loonie2 , loonie2 , LOONIE2 )
MAKEPREPOSTPARVAR ( Loonie3 , loonie3 , LOONIE3 )
MAKEPREPOSTPARVAR ( Loonie3D , loonie_3D , LOONIE3D )
MAKEPREPOSTPARVAR ( Mcarpet , mcarpet , MCARPET )
MAKEPREPOSTPARVAR ( Waves23D , waves2_3D , WAVES23D )
MAKEPREPOSTPARVARASSIGN ( Pie3D , pie3D , PIE3D , eVariationAssignType : : ASSIGNTYPE_SUM )
MAKEPREPOSTPARVAR ( Popcorn23D , popcorn2_3D , POPCORN23D )
MAKEPREPOSTVAR ( Sinusoidal3D , sinusoidal3D , SINUSOIDAL3D )
MAKEPREPOSTPARVAR ( Scry3D , scry_3D , SCRY3D )
MAKEPREPOSTPARVAR ( Shredlin , shredlin , SHRED_LIN )
MAKEPREPOSTPARVAR ( SplitBrdr , SplitBrdr , SPLIT_BRDR )
MAKEPREPOSTVAR ( Wdisc , wdisc , WDISC )
MAKEPREPOSTPARVAR ( Falloff , falloff , FALLOFF )
MAKEPREPOSTPARVAR ( Falloff2 , falloff2 , FALLOFF2 )
MAKEPREPOSTPARVAR ( Falloff3 , falloff3 , FALLOFF3 )
MAKEPREPOSTPARVAR ( Xtrb , xtrb , XTRB )
MAKEPREPOSTPARVAR ( Hexaplay3D , hexaplay3D , HEXAPLAY3D )
MAKEPREPOSTPARVAR ( Hexnix3D , hexnix3D , HEXNIX3D )
MAKEPREPOSTPARVAR ( Hexcrop , hexcrop , HEXCROP )
}