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 " ) ) ;
--User changes
-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
-Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
-Add a new button to toggle xaos on and off.
-When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
-When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
-Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
-Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
-Add the Circle_Rand variation from Chaotica.
-Add tool tips to clarify the following items:
--Auto Unique Filenames checkbox in the options dialog.
--Xaos table headers.
--Bug fixes
-Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
-Adding/removing nodes from the color curve had accidentally been disabled.
-The applied xaos weight table was not showing normalized weight values.
-Changing the size of a flame was not observing the Apply To All checkbox.
-Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
2023-11-22 00:58:22 -05:00
m_Params . push_back ( ParamWithName < T > ( true , & m_Fill , prefix + " cubic3D_fill " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
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 :
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
using Variation < T > : : m_NeedPrecalcSumSquares ;
using Variation < T > : : m_NeedPrecalcSqrtSumSquares ;
2023-04-25 19:59:54 -04:00
Loonie2Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " loonie2 " , eVariationId : : VAR_LOONIE2 , weight , true , true )
{
Init ( ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
m_NeedPrecalcSqrtSumSquares = Compat : : m_Compat ;
2023-04-25 19:59:54 -04:00
}
PARVARCOPY ( Loonie2Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
if ( Compat : : m_Compat )
2023-04-25 19:59:54 -04:00
{
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
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 ;
2023-04-25 19:59:54 -04:00
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
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 ) ;
}
2023-04-25 19:59:54 -04:00
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
r2 = r2 * m_Cosc + circle * m_Sinc ;
2023-04-25 19:59:54 -04:00
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
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 ;
}
2023-04-25 19:59:54 -04:00
}
else
{
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
T r2 = helper . m_PrecalcSumSquares ;
T r = r2 < T ( 1 ) ? std : : sqrt ( 1 / Zeps ( r2 ) - 1 ) : T ( 1 ) ;
T newX = helper . In . x * r ;
T newY = helper . In . y * r ;
T dang = ( std : : atan2 ( newY , newX ) + T ( M_PI ) ) / m_Alpha ;
T rad = std : : sqrt ( SQR ( newX ) + SQR ( newY ) ) ;
T zang1 = T ( Floor ( dang ) ) ;
T xang1 = dang - zang1 ;
T xang2 , zang , sign ;
if ( xang1 > T ( 0.5 ) )
{
xang2 = 1 - xang1 ;
zang = zang1 + 1 ;
sign = - 1 ;
}
else
{
xang2 = xang1 ;
zang = zang1 ;
sign = 1 ;
}
T xang = std : : atan ( xang2 * m_TanHalfAlpha2 ) / m_Alpha ;
T coeff = 1 / Zeps ( std : : cos ( xang * m_Alpha ) ) ;
T ang = ( zang + sign * xang ) * m_Alpha - T ( M_PI ) ;
T temp = m_Weight * coeff * rad ;
helper . Out . x = temp * std : : cos ( ang ) ;
helper . Out . y = temp * std : : sin ( ang ) ;
2023-04-25 19:59:54 -04:00
}
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 ( ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
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 power = " 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 ;
string alpha = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string tanhalfalpha2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
if ( Compat : : m_Compat )
{
ss < < " \t { \n "
< < " \t \t int i; \n "
< < " \t \t real_t weight = " < < weight < < " ; \n "
< < " \t \t real_t coss = " < < coss < < " ; \n "
< < " \t \t real_t sins = " < < sins < < " ; \n "
< < " \t \t real_t sina = " < < sina < < " ; \n "
< < " \t \t real_t cosa = " < < cosa < < " ; \n "
< < " \t \t real_t w2 = " < < w2 < < " ; \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 " ;
}
else
{
ss < < " \t { \n "
< < " \t \t real_t alpha = " < < alpha < < " ; \n "
< < " \t \t real_t r2 = precalcSumSquares; \n "
< < " \t \t real_t r = r2 < (real_t)(1.0) ? sqrt(1 / Zeps(r2) - 1) : (real_t)(1.0); \n "
< < " \t \t real_t newX = vIn.x * r; \n "
< < " \t \t real_t newY = vIn.y * r; \n "
< < " \t \t real_t dang = (atan2(newY, newX) + MPI) / alpha; \n "
< < " \t \t real_t rad = sqrt(SQR(newX) + SQR(newY)); \n "
< < " \t \t real_t zang1 = floor(dang); \n "
< < " \t \t real_t xang1 = dang - zang1; \n "
< < " \t \t real_t xang2, zang, sign; \n "
< < " \n "
< < " \t \t if (xang1 > 0.5) \n "
< < " \t \t { \n "
< < " \t \t xang2 = 1 - xang1; \n "
< < " \t \t zang = zang1 + 1; \n "
< < " \t \t sign = -1; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t xang2 = xang1; \n "
< < " \t \t zang = zang1; \n "
< < " \t \t sign = 1; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t real_t xang = atan(xang2 * " < < tanhalfalpha2 < < " ) / alpha; \n "
< < " \t \t real_t coeff = 1 / Zeps(cos(xang * alpha)); \n "
< < " \t \t real_t ang = (zang + sign * xang) * alpha - MPI; \n "
< < " \t \t real_t temp = " < < weight < < " * coeff * rad; \n "
< < " \t \t vOut.x = temp * cos(ang); \n "
< < " \t \t vOut.y = temp * sin(ang); \n " ;
}
ss < < " \t \t vOut.z = " < < DefaultZCl ( )
2023-04-25 19:59:54 -04:00
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
if ( Compat : : m_Compat )
{
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 ) ;
}
else
{
m_Alpha = M_2PI / Zeps ( m_Power ) ;
m_TanHalfAlpha2 = std : : tan ( m_Alpha * T ( 0.5 ) ) * 2 ;
}
m_NeedPrecalcSqrtSumSquares = Compat : : m_Compat ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
if ( Compat : : m_Compat )
return vector < string > { } ;
else
return vector < string > { " Zeps " } ;
2023-04-25 19:59:54 -04:00
}
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 ) ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
m_Params . push_back ( ParamWithName < T > ( & m_Power , prefix + " loonie2_power " , 4 ) ) ;
2023-04-25 19:59:54 -04:00
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 " ) ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
m_Params . push_back ( ParamWithName < T > ( true , & m_Alpha , prefix + " loonie2_alpha " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_TanHalfAlpha2 , prefix + " loonie2_tan_half_alpha2 " ) ) ;
2023-04-25 19:59:54 -04:00
}
private :
T m_Sides ;
T m_Star ;
T m_Circle ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
T m_Power ;
2023-04-25 19:59:54 -04:00
T m_W2 ; //Precalc.
T m_Sina ;
T m_Cosa ;
T m_Sins ;
T m_Coss ;
T m_Sinc ;
T m_Cosc ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
T m_Alpha ;
T m_TanHalfAlpha2 ;
2023-04-25 19:59:54 -04:00
} ;
/// <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 ) ) ;
--User changes
-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
-Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
-Add a new button to toggle xaos on and off.
-When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
-When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
-Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
-Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
-Add the Circle_Rand variation from Chaotica.
-Add tool tips to clarify the following items:
--Auto Unique Filenames checkbox in the options dialog.
--Xaos table headers.
--Bug fixes
-Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
-Adding/removing nodes from the color curve had accidentally been disabled.
-The applied xaos weight table was not showing normalized weight values.
-Changing the size of a flame was not observing the Apply To All checkbox.
-Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
2023-11-22 00:58:22 -05:00
m_Params . push_back ( ParamWithName < T > ( true , & m_SinTanC , prefix + " popcorn2_3D_sintanc " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
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 ) ) ;
--User changes
-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
-Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
-Add a new button to toggle xaos on and off.
-When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
-When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
-Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
-Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
-Add the Circle_Rand variation from Chaotica.
-Add tool tips to clarify the following items:
--Auto Unique Filenames checkbox in the options dialog.
--Xaos table headers.
--Bug fixes
-Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
-Adding/removing nodes from the color curve had accidentally been disabled.
-The applied xaos weight table was not showing normalized weight values.
-Changing the size of a flame was not observing the Apply To All checkbox.
-Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
2023-11-22 00:58:22 -05:00
m_Params . push_back ( ParamWithName < T > ( true , & m_Xw , prefix + " shredlin_xw " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
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 ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
helper . Out . x = m_Weight * Lerp < T > ( helper . In . x , 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 , 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 , Floor ( helper . In . z * denom ) + scale * az , m_MulZ * rs ) + m_MulZ * std : : pow ( az , m_BoxPow ) * rs * denom ;
2023-04-25 19:59:54 -04:00
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.
--User changes
-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
-Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
-Add a new button to toggle xaos on and off.
-When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
-When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
-Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
-Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
-Add the Circle_Rand variation from Chaotica.
-Add tool tips to clarify the following items:
--Auto Unique Filenames checkbox in the options dialog.
--Xaos table headers.
--Bug fixes
-Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
-Adding/removing nodes from the color curve had accidentally been disabled.
-The applied xaos weight table was not showing normalized weight values.
-Changing the size of a flame was not observing the Apply To All checkbox.
-Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
2023-11-22 00:58:22 -05:00
m_Params . push_back ( ParamWithName < T > ( true , & m_InternalScatter , prefix + " falloff_internal_scatter " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
}
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 ) ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
m_Params . push_back ( ParamWithName < T > ( & m_MulZ , prefix + " falloff2_mul_z " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_MulC , prefix + " falloff2_mul_c " ) ) ;
2023-04-25 19:59:54 -04:00
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 " ) ) ;
--User changes
-Update various tooltips.
-Increase precision of affine and xaos spinners.
-Increase precision of fields written in Xml files to 8.
--Bug fixes
-When rendering on the CPU, if the number of threads didn't divide evenly into the number of rows, it would leave a blank spot on the last few rows.
-Fix numerous parsing bugs when reading .chaos files.
-Added compatibility fixes and/or optimizations to the following variations: asteria, bcircle, bcollide, bipolar, blob2, btransform, cell, circlecrop, circlecrop2, collideoscope, cpow2, cropn, cross, curl, depth_ngon2, depth_sine2, edisc, eRotate, escher, fan2, hex_rand, hypershift, hypershift2, hypertile1, julia, julian, julian2, juliaq, juliascope, lazyjess, log, loonie2, murl, murl2, npolar, oscilloscope2, perspective, phoenix_julia, sphericaln, squish, starblur, starblur2, truchet, truchet_glyph, waffle, wavesn.
2023-11-29 17:47:31 -05:00
m_Params . push_back ( ParamWithName < T > ( & m_Invert , prefix + " falloff2_invert " , 0 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Type , prefix + " falloff2_type " , 0 , eParamType : : REAL , 0 , 2 ) ) ;
2023-04-25 19:59:54 -04:00
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 )
--User changes
-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
-Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
-Add a new button to toggle xaos on and off.
-When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
-When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
-Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
-Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
-Add the Circle_Rand variation from Chaotica.
-Add tool tips to clarify the following items:
--Auto Unique Filenames checkbox in the options dialog.
--Xaos table headers.
--Bug fixes
-Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
-Adding/removing nodes from the color curve had accidentally been disabled.
-The applied xaos weight table was not showing normalized weight values.
-Changing the size of a flame was not observing the Apply To All checkbox.
-Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
2023-11-22 00:58:22 -05:00
//Boost is the separation distance between the two planes.
2023-04-25 19:59:54 -04:00
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 )
}