2023-04-25 19:59:54 -04:00
# pragma once
# include "Variation.h"
namespace EmberNs
{
/// <summary>
/// hexes.
/// </summary>
template < typename T >
class HexesVariation : public ParametricVariation < T >
{
public :
HexesVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " hexes " , eVariationId : : VAR_HEXES , weight )
{
Init ( ) ;
}
PARVARCOPY ( HexesVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
// Xh = (Xo + sqrt(3) * Yo) / (3 * l)
static const T AXhXo = T ( 1.0 / 3.0 ) ;
static const T AXhYo = T ( 1.7320508075688772935 / 3.0 ) ;
// Now: Xh = ( AXhXo * Xo + AXhYo * Yo ) / l;
// Yh = (-Xo + sqrt(3) * Yo) / (3 * l)
static const T AYhXo = T ( - 1.0 / 3.0 ) ;
static const T AYhYo = T ( 1.7320508075688772935 / 3.0 ) ;
// Now: Yh = ( AYhXo * Xo + AYhYo * Yo ) / l;
// Xo = 3/2 * l * (Xh - Yh)
static const T AXoXh = T ( 1.5 ) ;
static const T AXoYh = T ( - 1.5 ) ;
// Now: Xo = ( AXoXh * Xh + AXoYh * Yh ) * l;
// Yo = sqrt(3)/2 * l * (Xh + Yh)
static const T AYoXh = T ( 1.7320508075688772935 / 2.0 ) ;
static const T AYoYh = T ( 1.7320508075688772935 / 2.0 ) ;
static const v2T offset [ 4 ] { { 0 , 0 } , { 0 , 1 } , { 1 , 0 } , { 1 , 1 } } ;
int i , j ;
T di , dj ;
T XCh , YCh , XCo , YCo , DXo , DYo , L , L1 , L2 , R , s , trgL ;
v2T u , v ;
v2T P [ 7 ] ;
//For speed/convenience.
s = m_Cellsize ;
//Infinite number of small cells? No effect . . .
if ( s = = 0 )
{
helper . Out . x = 0 ;
helper . Out . y = 0 ;
helper . Out . z = DefaultZ ( helper ) ;
return ;
}
//Get co-ordinates, and convert to hex co-ordinates.
u . x = helper . In . x ;
u . y = helper . In . y ;
XCh = T ( Floor ( ( AXhXo * u . x + AXhYo * u . y ) / s ) ) ;
YCh = T ( Floor ( ( AYhXo * u . x + AYhYo * u . y ) / s ) ) ;
// Get a set of 4 hex center points, based around the one above
for ( i = 0 , di = XCh ; i < 2 ; di + = 1 , i + + ) //Note that in SP mode, these numbers won't advance if they are on the boundary of what can be represented with an DP number...
{
for ( j = 0 , dj = YCh ; j < 2 ; dj + = 1 , j + + ) //...which is why the check uses i and j.
{
P [ ( i * 2 ) + j ] . x = ( AXoXh * di + AXoYh * dj ) * s ;
P [ ( i * 2 ) + j ] . y = ( AYoXh * di + AYoYh * dj ) * s ;
}
}
int q = m_VarFuncs - > Closest ( & P [ 0 ] , 4 , u ) ;
//Remake list starting from chosen hex, ensure it is completely surrounded (total 7 points).
//First adjust centers according to which one was found to be closest.
XCh + = offset [ q ] . x ;
YCh + = offset [ q ] . y ;
//First point is central/closest.
XCo = ( AXoXh * XCh + AXoYh * YCh ) * s ;
YCo = ( AYoXh * XCh + AYoYh * YCh ) * s ;
P [ 0 ] . x = XCo ;
P [ 0 ] . y = YCo ;
//Next six points are based on hex graph (6 hexes around center). As long as
//center points are not too distorted from simple hex, this defines all possible edges.
//In hex co-ords, offsets are: (0,1) (1,1) (1,0) (0,-1) (-1,-1) (-1, 0).
P [ 1 ] . x = XCo + ( AXoYh ) * s ;
P [ 1 ] . y = YCo + ( AYoYh ) * s ;
P [ 2 ] . x = XCo + ( AXoXh + AXoYh ) * s ;
P [ 2 ] . y = YCo + ( AYoXh + AYoYh ) * s ;
P [ 3 ] . x = XCo + ( AXoXh ) * s ;
P [ 3 ] . y = YCo + ( AYoXh ) * s ;
P [ 4 ] . x = XCo - AXoYh * s ;
P [ 4 ] . y = YCo - AYoYh * s ;
P [ 5 ] . x = XCo - ( AXoXh + AXoYh ) * s ;
P [ 5 ] . y = YCo - ( AYoXh + AYoYh ) * s ;
P [ 6 ] . x = XCo - AXoXh * s ;
P [ 6 ] . y = YCo - AYoXh * s ;
L1 = m_VarFuncs - > Voronoi ( & P [ 0 ] , 7 , 0 , u ) ;
//Delta vector from center of hex.
DXo = u . x - P [ 0 ] . x ;
DYo = u . y - P [ 0 ] . y ;
//Apply "interesting bit" to cell's DXo and DYo co-ordinates.
//trgL is the defined value of l, independent of any rotation.
trgL = std : : pow ( std : : abs ( L1 ) , m_Power ) * m_Scale ; //Original added 1e-100, use Zeps to be more precise.
//Rotate.
v . x = DXo * m_RotCos + DYo * m_RotSin ;
v . y = - DXo * m_RotSin + DYo * m_RotCos ;
//Measure voronoi distance again.
u = v + P [ 0 ] ;
L2 = m_VarFuncs - > Voronoi ( & P [ 0 ] , 7 , 0 , u ) ;
//Scale to meet target size . . . adjust according to how close
//we are to the edge.
//Code here attempts to remove the "rosette" effect caused by
//scaling between.
//L is maximum of L1 or L2 . . .
//When L = 0.8 or higher . . . match trgL/L2 exactly.
//When L = T(0.5) or less . . . match trgL/L1 exactly.
L = std : : max ( L1 , L2 ) ;
if ( L < T ( 0.5 ) )
{
R = trgL / L1 ;
}
else
{
if ( L > T ( 0.8 ) )
R = trgL / L2 ;
else
R = ( ( trgL / L1 ) * ( T ( 0.8 ) - L ) + ( trgL / L2 ) * ( L - T ( 0.5 ) ) ) / T ( 0.3 ) ;
}
v * = R ;
//Add cell center co-ordinates back in.
v + = P [ 0 ] ;
//Finally add values in.
helper . Out . x = m_Weight * v . x ;
helper . Out . y = m_Weight * v . 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 cellsize = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string power = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rotate = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rotsin = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rotcos = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int i, j; \n "
< < " \t \t real_t di, dj; \n "
< < " \t \t real_t XCh, YCh, XCo, YCo, DXo, DYo, L, L1, L2, R, s, trgL, Vx, Vy; \n "
< < " \t \t real2 U; \n "
< < " \t \t real2 P[7]; \n "
< < " \n "
< < " \t \t s = " < < cellsize < < " ; \n "
< < " \n "
< < " \t \t if (s == 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = 0; \n "
< < " \t \t vOut.y = 0; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t \t return; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t U.x = vIn.x; \n "
< < " \t \t U.y = vIn.y; \n "
< < " \n "
< < " \t \t XCh = floor(fma(AXhXo, U.x, AXhYo * U.y) / s); \n "
< < " \t \t YCh = floor(fma(AYhXo, U.x, AYhYo * U.y) / s); \n "
< < " \n "
< < " \t \t for (i = 0, di = XCh; i < 2; di += 1, i++) \n "
< < " \t \t { \n "
< < " \t \t for (j = 0, dj = YCh; j < 2; dj += 1, j++) \n "
< < " \t \t { \n "
< < " \t \t P[(i * 2) + j].x = fma(AXoXh, di, AXoYh * dj) * s; \n "
< < " \t \t P[(i * 2) + j].y = fma(AYoXh, di, AYoYh * dj) * s; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t int q = Closest(&P[0], 4, &U); \n "
< < " \n "
< < " \t \t XCh += offset[q].x; \n "
< < " \t \t YCh += offset[q].y; \n "
< < " \n "
< < " \t \t XCo = fma(AXoXh, XCh, AXoYh * YCh) * s; \n "
< < " \t \t YCo = fma(AYoXh, XCh, AYoYh * YCh) * s; \n "
< < " \t \t P[0].x = XCo; \n "
< < " \t \t P[0].y = YCo; \n "
< < " \n "
< < " \t \t P[1].x = XCo + (AXoYh)* s; \n "
< < " \t \t P[1].y = YCo + (AYoYh)* s; \n "
< < " \t \t P[2].x = XCo + (AXoXh + AXoYh) * s; \n "
< < " \t \t P[2].y = YCo + (AYoXh + AYoYh) * s; \n "
< < " \t \t P[3].x = XCo + (AXoXh)* s; \n "
< < " \t \t P[3].y = YCo + (AYoXh)* s; \n "
< < " \t \t P[4].x = XCo - AXoYh * s; \n "
< < " \t \t P[4].y = YCo - AYoYh * s; \n "
< < " \t \t P[5].x = XCo - (AXoXh + AXoYh) * s; \n "
< < " \t \t P[5].y = YCo - (AYoXh + AYoYh) * s; \n "
< < " \t \t P[6].x = XCo - AXoXh * s; \n "
< < " \t \t P[6].y = YCo - AYoXh * s; \n "
< < " \n "
< < " \t \t L1 = Voronoi(&P[0], 7, 0, &U); \n "
< < " \n "
< < " \t \t DXo = U.x - P[0].x; \n "
< < " \t \t DYo = U.y - P[0].y; \n "
< < " \n "
< < " \t \t trgL = pow(fabs(L1), " < < power < < " ) * " < < scale < < " ; \n "
< < " \n "
< < " \t \t Vx = fma( DXo, " < < rotcos < < " , DYo * " < < rotsin < < " ); \n "
< < " \t \t Vy = fma(-DXo, " < < rotsin < < " , DYo * " < < rotcos < < " ); \n "
< < " \n "
< < " \t \t U.x = Vx + P[0].x; \n "
< < " \t \t U.y = Vy + P[0].y; \n "
< < " \t \t L2 = Voronoi(&P[0], 7, 0, &U); \n "
< < " \t \t L = max(L1, L2); \n "
< < " \n "
< < " \t \t if (L < 0.5) \n "
< < " \t \t { \n "
< < " \t \t R = trgL / L1; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if (L > 0.8) \n "
< < " \t \t R = trgL / L2; \n "
< < " \t \t else \n "
< < " \t \t R = fma(trgL / L1, (real_t)(0.8) - L, (trgL / L2) * (L - (real_t)(0.5))) / 0.3; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t Vx *= R; \n "
< < " \t \t Vy *= R; \n "
< < " \n "
< < " \t \t Vx += P[0].x; \n "
< < " \t \t Vy += P[0].y; \n "
< < " \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " , " Sqr " , " Vratio " , " Voronoi " , " Closest " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" constant real_t AXhXo = (real_t)(1.0 / 3.0); \n "
" constant real_t AXhYo = (real_t)(1.7320508075688772935 / 3.0); \n "
" constant real_t AYhXo = (real_t)(-1.0 / 3.0); \n "
" constant real_t AYhYo = (real_t)(1.7320508075688772935 / 3.0); \n "
" constant real_t AXoXh = (real_t)(1.5); \n "
" constant real_t AXoYh = (real_t)(-1.5); \n "
" constant real_t AYoXh = (real_t)(1.7320508075688772935 / 2.0); \n "
" constant real_t AYoYh = (real_t)(1.7320508075688772935 / 2.0); \n "
" constant real2 offset[4] = { { 0, 0 }, { 0, 1 }, { 1, 0 }, { 1, 1 } }; \n "
" \n " ;
}
virtual void Precalc ( ) override
{
m_RotSin = std : : sin ( m_Rotate * M_2PI ) ;
m_RotCos = std : : cos ( m_Rotate * M_2PI ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Cellsize , prefix + " hexes_cellsize " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Power , prefix + " hexes_power " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Rotate , prefix + " hexes_rotate " , T ( 0.166 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scale , prefix + " hexes_scale " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RotSin , prefix + " hexes_rotsin " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_RotCos , prefix + " hexes_rotcos " ) ) ;
}
private :
T m_Cellsize ;
T m_Power ;
T m_Rotate ;
T m_Scale ;
T m_RotSin ; //Precalc.
T m_RotCos ;
shared_ptr < VarFuncs < T > > m_VarFuncs = VarFuncs < T > : : Instance ( ) ;
} ;
/// <summary>
/// nBlur.
/// </summary>
template < typename T >
class NblurVariation : public ParametricVariation < T >
{
struct RandXyParams
{
T NumEdges ;
T RatioHole ;
T CircumCircle ;
T EqualBlur ;
T ExactCalc ;
T MidAngle ;
T AngStart ;
T AngStripes ;
T HasStripes ;
T NegStripes ;
T MaxStripes ;
T Tan90M2 ;
T ArcTan1 ;
T ArcTan2 ;
T RatioStripes ;
T RatioComplement ;
T SpeedCalc1 ;
T SpeedCalc2 ;
T LenInnerEdges ;
T LenOuterEdges ;
T X ;
T Y ;
T LenXY ;
} ;
public :
NblurVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " nBlur " , eVariationId : : VAR_NBLUR , weight )
{
Init ( ) ;
}
PARVARCOPY ( NblurVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T xTmp , yTmp ;
RandXyParams params ;
params . NumEdges = m_NumEdges ;
params . RatioHole = m_RatioHole ;
params . CircumCircle = m_CircumCircle ;
params . EqualBlur = m_EqualBlur ;
params . ExactCalc = m_ExactCalc ;
params . MidAngle = m_MidAngle ;
params . AngStart = m_AngStart ;
params . AngStripes = m_AngStripes ;
params . HasStripes = m_HasStripes ;
params . NegStripes = m_NegStripes ;
params . MaxStripes = m_MaxStripes ;
params . Tan90M2 = m_Tan90M2 ;
params . ArcTan1 = m_ArcTan1 ;
params . ArcTan2 = m_ArcTan2 ;
params . RatioStripes = m_RatioStripes ;
params . RatioComplement = m_RatioComplement ;
params . SpeedCalc1 = m_SpeedCalc1 ;
params . SpeedCalc2 = m_SpeedCalc2 ;
RandXY ( params , rand ) ;
if ( ( m_ExactCalc = = 1 ) & & ( m_CircumCircle = = 0 ) )
while ( ( params . LenXY < params . LenInnerEdges ) | | ( params . LenXY > params . LenOuterEdges ) )
RandXY ( params , rand ) ;
if ( ( m_ExactCalc = = 1 ) & & ( m_CircumCircle = = 1 ) )
while ( params . LenXY < params . LenInnerEdges )
RandXY ( params , rand ) ;
xTmp = params . X ;
yTmp = params . Y ;
params . X = m_Cosa * xTmp - m_Sina * yTmp ;
params . Y = m_Sina * xTmp + m_Cosa * yTmp ;
helper . Out . x = m_AdjustedWeight * params . X ;
helper . Out . y = m_AdjustedWeight * params . 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 numEdges = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string numStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ratioStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ratioHole = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string circumCircle = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string adjustToLinear = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string equalBlur = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string exactCalc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string highlightEdges = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ratioComplement = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc.
string midAngle = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angStart = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hasStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string negStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string maxStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string absStripes = " 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 tan90M2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string arcTan1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string arcTan2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string speedCalc1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string speedCalc2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string adjustedWeight = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t xTmp, yTmp; \n "
< < " \t \t RandXyParams params; \n "
< < " \n "
< < " \t \t params.NumEdges = " < < numEdges < < " ; \n "
< < " \t \t params.RatioHole = " < < ratioHole < < " ; \n "
< < " \t \t params.CircumCircle = " < < circumCircle < < " ; \n "
< < " \t \t params.EqualBlur = " < < equalBlur < < " ; \n "
< < " \t \t params.ExactCalc = " < < exactCalc < < " ; \n "
< < " \t \t params.MidAngle = " < < midAngle < < " ; \n "
< < " \t \t params.AngStart = " < < angStart < < " ; \n "
< < " \t \t params.AngStripes = " < < angStripes < < " ; \n "
< < " \t \t params.HasStripes = " < < hasStripes < < " ; \n "
< < " \t \t params.NegStripes = " < < negStripes < < " ; \n "
< < " \t \t params.MaxStripes = " < < maxStripes < < " ; \n "
< < " \t \t params.Tan90M2 = " < < tan90M2 < < " ; \n "
< < " \t \t params.ArcTan1 = " < < arcTan1 < < " ; \n "
< < " \t \t params.ArcTan2 = " < < arcTan2 < < " ; \n "
< < " \t \t params.RatioStripes = " < < ratioStripes < < " ; \n "
< < " \t \t params.RatioComplement = " < < ratioComplement < < " ; \n "
< < " \t \t params.SpeedCalc1 = " < < speedCalc1 < < " ; \n "
< < " \t \t params.SpeedCalc2 = " < < speedCalc2 < < " ; \n "
< < " \n "
< < " \t \t RandXY(¶ms, mwc); \n "
< < " \n "
< < " \t \t if (( " < < exactCalc < < " == 1) && ( " < < circumCircle < < " == 0)) \n "
< < " \t \t while ((params.LenXY < params.LenInnerEdges) || (params.LenXY > params.LenOuterEdges)) \n "
< < " \t \t RandXY(¶ms, mwc); \n "
< < " \n "
< < " \t \t if (( " < < exactCalc < < " == 1) && ( " < < circumCircle < < " == 1)) \n "
< < " \t \t while (params.LenXY < params.LenInnerEdges) \n "
< < " \t \t RandXY(¶ms, mwc); \n "
< < " \n "
< < " \t \t xTmp = params.X; \n "
< < " \t \t yTmp = params.Y; \n "
< < " \n "
< < " \t \t params.X = fma( " < < cosa < < " , xTmp, -( " < < sina < < " * yTmp)); \n "
< < " \t \t params.Y = fma( " < < sina < < " , xTmp, " < < cosa < < " * yTmp); \n "
< < " \n "
< < " \t \t vOut.x = " < < adjustedWeight < < " * params.X; \n "
< < " \t \t vOut.y = " < < adjustedWeight < < " * params.Y; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Swap " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" typedef struct __attribute__ " ALIGN_CL " _RandXyParams \n "
" { \n "
" real_t NumEdges; \n "
" real_t RatioHole; \n "
" real_t CircumCircle; \n "
" real_t EqualBlur; \n "
" real_t ExactCalc; \n "
" real_t MidAngle; \n "
" real_t AngStart; \n "
" real_t AngStripes; \n "
" real_t HasStripes; \n "
" real_t NegStripes; \n "
" real_t MaxStripes; \n "
" real_t Tan90M2; \n "
" real_t ArcTan1; \n "
" real_t ArcTan2; \n "
" real_t RatioStripes; \n "
" real_t RatioComplement; \n "
" real_t SpeedCalc1; \n "
" real_t SpeedCalc2; \n "
" real_t LenInnerEdges; \n "
" real_t LenOuterEdges; \n "
" real_t X; \n "
" real_t Y; \n "
" real_t LenXY; \n "
" } RandXyParams; \n "
" \n "
" static void RandXY(RandXyParams* params, uint2* mwc) \n "
" { \n "
" real_t angXY, angMem, angTmp; \n "
" real_t ratioTmp, ratioTmpNum, ratioTmpDen; \n "
" real_t xTmp, yTmp; \n "
" real_t ranTmp; \n "
" int count; \n "
" \n "
" if (params->ExactCalc == 1) \n "
" angXY = MwcNext01(mwc) * M_2PI; \n "
" else \n "
" angXY = (atan(params->ArcTan1 * (MwcNext01(mwc) - 0.5)) / params->ArcTan2 + 0.5 + (real_t)(MwcNextRange(mwc, (uint)params->NumEdges))) * params->MidAngle; \n "
" \n "
" params->X = sincos(angXY, ¶ms->Y); \n "
" angMem = angXY; \n "
" \n "
" while (angXY > params->MidAngle) \n "
" angXY -= params->MidAngle; \n "
" \n "
" if (params->HasStripes == 1) \n "
" { \n "
" count = 0; \n "
" angTmp = params->AngStart; \n "
" \n "
" while (angXY > angTmp) \n "
" { \n "
" angTmp += params->AngStripes; \n "
" \n "
" if (angTmp > params->MidAngle) \n "
" angTmp = params->MidAngle; \n "
" \n "
" count++; \n "
" } \n "
" \n "
" if (angTmp != params->MidAngle) \n "
" angTmp -= params->AngStart; \n "
" \n "
" if (params->NegStripes == 0) \n "
" { \n "
" if ((count & 1) == 1) \n "
" { \n "
" if (angXY > angTmp) \n "
" { \n "
" angXY = angXY + params->AngStart; \n "
" angMem = angMem + params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" angTmp += params->AngStripes; \n "
" count++; \n "
" } \n "
" else \n "
" { \n "
" angXY = angXY - params->AngStart; \n "
" angMem = angMem - params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" angTmp -= params->AngStripes; \n "
" count--; \n "
" } \n "
" } \n "
" \n "
" if (((count & 1) == 0) && (params->RatioStripes > 1)) \n "
" { \n "
" if ((angXY > angTmp) && (count != params->MaxStripes)) \n "
" { \n "
" angMem = angMem - angXY + angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" angXY = angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" } \n "
" else \n "
" { \n "
" angMem = angMem - angXY + angTmp - (angTmp - angXY) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" angXY = angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" } \n "
" } \n "
" \n "
" if (((count & 1) == 0) && (params->RatioStripes < 1)) \n "
" { \n "
" if ((fabs(angXY - angTmp) > params->SpeedCalc2) && (count != params->MaxStripes)) \n "
" { \n "
" if ((angXY - angTmp) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angXY - (angTmp + params->SpeedCalc2)) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp + ratioTmp), ¶ms->Y); \n "
" angXY = angTmp + ratioTmp; \n "
" } \n "
" \n "
" if ((angTmp - angXY) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angTmp - params->SpeedCalc2 - angXY) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp - ratioTmp), ¶ms->Y); \n "
" angXY = angTmp - ratioTmp; \n "
" } \n "
" } \n "
" \n "
" if (count == params->MaxStripes) \n "
" { \n "
" if ((angTmp - angXY) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angTmp - params->SpeedCalc2 - angXY) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp - ratioTmp), ¶ms->Y); \n "
" angXY = angTmp - ratioTmp; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" else \n "
" { \n "
" Swap(¶ms->RatioStripes, ¶ms->RatioComplement); \n "
" Swap(¶ms->SpeedCalc1, ¶ms->SpeedCalc2); \n "
" \n "
" if ((count & 1) == 0) \n "
" { \n "
" if ((angXY > angTmp) && (count != params->MaxStripes)) \n "
" { \n "
" angXY = angXY + params->AngStart; \n "
" angMem = angMem + params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" angTmp += params->AngStripes; \n "
" count++; \n "
" } \n "
" else \n "
" { \n "
" angXY = angXY - params->AngStart; \n "
" angMem = angMem - params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" angTmp -= params->AngStripes; \n "
" count--; \n "
" } \n "
" } \n "
" \n "
" if (((count & 1) == 1) && (params->RatioStripes > 1)) \n "
" { \n "
" if ((angXY > angTmp) && (count != params->MaxStripes)) \n "
" { \n "
" angMem = angMem - angXY + angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" angXY = angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" } \n "
" else \n "
" { \n "
" angMem = angMem - angXY + angTmp - (angTmp - angXY) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" angXY = angTmp + (angXY - angTmp) / params->AngStart * params->RatioStripes * params->AngStart; \n "
" params->X = sincos(angMem, ¶ms->Y); \n "
" } \n "
" } \n "
" \n "
" if (((count & 1) == 1) && (params->RatioStripes < 1)) \n "
" { \n "
" if ((fabs(angXY - angTmp) > params->SpeedCalc2) && (count != params->MaxStripes)) \n "
" { \n "
" if ((angXY - angTmp) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angXY - (angTmp + params->SpeedCalc2)) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp + ratioTmp), ¶ms->Y); \n "
" angXY = angTmp + ratioTmp; \n "
" } \n "
" \n "
" if ((angTmp - angXY) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angTmp - params->SpeedCalc2 - angXY) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp - ratioTmp), ¶ms->Y); \n "
" angXY = angTmp - ratioTmp; \n "
" } \n "
" } \n "
" \n "
" if (count == params->MaxStripes) \n "
" { \n "
" angTmp = params->MidAngle; \n "
" \n "
" if ((angTmp - angXY) > params->SpeedCalc2) \n "
" { \n "
" ratioTmpNum = (angTmp - params->SpeedCalc2 - angXY) * params->SpeedCalc2; \n "
" ratioTmpDen = params->AngStart - params->SpeedCalc2; \n "
" ratioTmp = ratioTmpNum / ratioTmpDen; \n "
" params->X = sincos((angMem - angXY + angTmp - ratioTmp), ¶ms->Y); \n "
" angXY = angTmp - ratioTmp; \n "
" } \n "
" } \n "
" } \n "
" \n "
" Swap(¶ms->RatioStripes, ¶ms->RatioComplement); \n "
" Swap(¶ms->SpeedCalc1, ¶ms->SpeedCalc2); \n "
" } \n "
" } \n "
" \n "
" xTmp = params->Tan90M2 / (params->Tan90M2 - tan(angXY)); \n "
" yTmp = xTmp * tan(angXY); \n "
" params->LenOuterEdges = sqrt(fma(xTmp, xTmp, SQR(yTmp))); \n "
" \n "
" if (params->ExactCalc == 1) \n "
" { \n "
" if (params->EqualBlur == 1) \n "
" ranTmp = sqrt(MwcNext01(mwc)); \n "
" else \n "
" ranTmp = MwcNext01(mwc); \n "
" } \n "
" else \n "
" { \n "
" if (params->CircumCircle == 1) \n "
" { \n "
" if (params->EqualBlur == 1) \n "
" ranTmp = sqrt(MwcNext01(mwc)); \n "
" else \n "
" ranTmp = MwcNext01(mwc); \n "
" } \n "
" else \n "
" { \n "
" if (params->EqualBlur == 1) \n "
" ranTmp = sqrt(MwcNext01(mwc)) * params->LenOuterEdges; \n "
" else \n "
" ranTmp = MwcNext01(mwc) * params->LenOuterEdges; \n "
" } \n "
" } \n "
" \n "
" params->LenInnerEdges = params->RatioHole * params->LenOuterEdges; \n "
" \n "
" if (params->ExactCalc == 0) \n "
" { \n "
" if (ranTmp < params->LenInnerEdges) \n "
" { \n "
" if (params->CircumCircle == 1) \n "
" { \n "
" if (params->EqualBlur == 1) \n "
" ranTmp = fma(sqrt(MwcNext01(mwc)), (1 - params->LenInnerEdges + EPS), params->LenInnerEdges); \n "
" else \n "
" ranTmp = fma(MwcNext01(mwc), (1 - params->LenInnerEdges + EPS), params->LenInnerEdges); \n "
" } \n "
" else \n "
" { \n "
" if (params->EqualBlur == 1) \n "
" ranTmp = fma(sqrt(MwcNext01(mwc)), (params->LenOuterEdges - params->LenInnerEdges), params->LenInnerEdges); \n "
" else \n "
" ranTmp = fma(MwcNext01(mwc), (params->LenOuterEdges - params->LenInnerEdges), params->LenInnerEdges); \n "
" } \n "
" } \n "
" } \n "
" \n "
" params->X *= ranTmp; \n "
" params->Y *= ranTmp; \n "
" params->LenXY = sqrt(fma(params->X, params->X, SQR(params->Y))); \n "
" } \n \n "
;
}
virtual void Precalc ( ) override
{
if ( m_NumEdges < 3 )
m_NumEdges = 3 ;
if ( m_NumStripes ! = 0 )
{
m_HasStripes = 1 ;
if ( m_NumStripes < 0 )
m_NegStripes = 1 ;
else
m_NegStripes = 0 ;
}
else
{
m_HasStripes = 0 ;
m_NegStripes = 0 ;
}
m_AbsStripes = std : : abs ( m_NumStripes ) ;
m_MidAngle = M_2PI / m_NumEdges ;
if ( m_HasStripes = = 1 )
{
m_AngStripes = m_MidAngle / ( 2 * m_AbsStripes ) ;
m_AngStart = m_AngStripes / 2 ;
m_RatioComplement = 2 - m_RatioStripes ;
}
if ( ( m_RatioHole > T ( 0.95 ) ) & & ( m_ExactCalc = = 1 ) & & ( m_CircumCircle = = 0 ) )
m_RatioHole = T ( 0.95 ) ;
m_Tan90M2 = std : : tan ( T ( M_PI_2 ) + m_MidAngle / 2 ) ;
sincos ( ( m_MidAngle / 2 ) , & m_Sina , & m_Cosa ) ;
if ( m_HighlightEdges < = 0.1 )
m_HighlightEdges = T ( 0.1 ) ;
if ( m_AdjustToLinear = = 1 )
{
if ( int ( m_NumEdges ) % 4 = = 0 )
m_AdjustedWeight = m_Weight / Zeps ( std : : sqrt ( 2 - 2 * std : : cos ( m_MidAngle * ( m_NumEdges / 2 - 1 ) ) ) / 2 ) ;
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
m_AdjustedWeight = m_Weight / Zeps ( std : : sqrt ( 2 - 2 * std : : cos ( m_MidAngle * Floor ( ( m_NumEdges / 2 ) ) ) ) / 2 ) ;
2023-04-25 19:59:54 -04:00
}
else
m_AdjustedWeight = m_Weight ;
if ( m_CircumCircle = = 1 )
{
m_ExactCalc = 0 ;
m_HighlightEdges = T ( 0.1 ) ;
}
m_SpeedCalc1 = m_RatioComplement * m_AngStart ;
m_SpeedCalc2 = m_RatioStripes * m_AngStart ;
m_MaxStripes = 2 * m_AbsStripes ;
if ( m_NegStripes = = 0 )
{
m_ArcTan1 = ( 13 / std : : pow ( m_NumEdges , T ( 1.3 ) ) ) * m_HighlightEdges ;
m_ArcTan2 = ( 2 * std : : atan ( m_ArcTan1 / - 2 ) ) ;
}
else
{
m_ArcTan1 = ( T ( 7.5 ) / std : : pow ( m_NumEdges , T ( 1.3 ) ) ) * m_HighlightEdges ;
m_ArcTan2 = 2 * std : : atan ( m_ArcTan1 / - 2 ) ;
}
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 25 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_NumEdges , prefix + " nBlur_numEdges " , 3 , eParamType : : INTEGER ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_NumStripes , prefix + " nBlur_numStripes " , 0 , eParamType : : INTEGER ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_RatioStripes , prefix + " nBlur_ratioStripes " , 1 , eParamType : : REAL , 0 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_RatioHole , prefix + " nBlur_ratioHole " , 0 , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CircumCircle , prefix + " nBlur_circumCircle " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_AdjustToLinear , prefix + " nBlur_adjustToLinear " , 1 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_EqualBlur , prefix + " nBlur_equalBlur " , 1 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ExactCalc , prefix + " nBlur_exactCalc " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HighlightEdges , prefix + " nBlur_highlightEdges " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RatioComplement , prefix + " nBlur_ratioComplement " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_MidAngle , prefix + " nBlur_midAngle " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngStart , prefix + " nBlur_angStart " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngStripes , prefix + " nBlur_angStripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HasStripes , prefix + " nBlur_hasStripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_NegStripes , prefix + " nBlur_negStripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_MaxStripes , prefix + " nBlur_maxStripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsStripes , prefix + " nBlur_absStripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Sina , prefix + " nBlur_sina " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Cosa , prefix + " nBlur_cosa " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Tan90M2 , prefix + " nBlur_tan90m2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_ArcTan1 , prefix + " nBlur_arcTan1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_ArcTan2 , prefix + " nBlur_arcTan2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SpeedCalc1 , prefix + " nBlur_speedCalc1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SpeedCalc2 , prefix + " nBlur_speedCalc2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AdjustedWeight , prefix + " nBlur_adjustedWeight " ) ) ;
}
private :
static void RandXY ( RandXyParams & params , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand )
{
T angXY , angMem , angTmp ;
T ratioTmp , ratioTmpNum , ratioTmpDen ;
T xTmp , yTmp ;
T ranTmp , x ;
int count ;
if ( params . ExactCalc = = 1 )
angXY = rand . Frand01 < T > ( ) * M_2PI ;
else
angXY = ( std : : atan ( params . ArcTan1 * ( rand . Frand01 < T > ( ) - T ( 0.5 ) ) ) / params . ArcTan2 + T ( 0.5 ) + T ( rand . Rand ( size_t ( params . NumEdges ) ) ) ) * params . MidAngle ;
sincos ( angXY , & params . X , & params . Y ) ;
angMem = angXY ;
while ( angXY > params . MidAngle )
angXY - = params . MidAngle ;
if ( params . HasStripes = = 1 )
{
count = 0 ;
angTmp = params . AngStart ;
while ( angXY > angTmp )
{
angTmp + = params . AngStripes ;
if ( angTmp > params . MidAngle )
angTmp = params . MidAngle ;
count + + ;
}
if ( angTmp ! = params . MidAngle )
angTmp - = params . AngStart ;
if ( params . NegStripes = = 0 )
{
if ( ( count & 1 ) = = 1 )
{
if ( angXY > angTmp )
{
angXY = angXY + params . AngStart ;
angMem = angMem + params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
angTmp + = params . AngStripes ;
count + + ;
}
else
{
angXY = angXY - params . AngStart ;
angMem = angMem - params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
angTmp - = params . AngStripes ;
count - - ;
}
}
if ( ( ( count & 1 ) = = 0 ) & & ( params . RatioStripes > 1 ) )
{
if ( ( angXY > angTmp ) & & ( count ! = params . MaxStripes ) )
{
angMem = angMem - angXY + angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
angXY = angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
}
else
{
angMem = angMem - angXY + angTmp - ( angTmp - angXY ) / params . AngStart * params . RatioStripes * params . AngStart ;
angXY = angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
}
}
if ( ( ( count & 1 ) = = 0 ) & & ( params . RatioStripes < 1 ) )
{
if ( ( std : : abs ( angXY - angTmp ) > params . SpeedCalc2 ) & & ( count ! = params . MaxStripes ) )
{
if ( ( angXY - angTmp ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angXY - ( angTmp + params . SpeedCalc2 ) ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp + ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp + ratioTmp ;
}
if ( ( angTmp - angXY ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angTmp - params . SpeedCalc2 - angXY ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp - ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp - ratioTmp ;
}
}
if ( count = = params . MaxStripes )
{
if ( ( angTmp - angXY ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angTmp - params . SpeedCalc2 - angXY ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp - ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp - ratioTmp ;
}
}
}
}
else
{
std : : swap ( params . RatioStripes , params . RatioComplement ) ;
std : : swap ( params . SpeedCalc1 , params . SpeedCalc2 ) ;
if ( ( count & 1 ) = = 0 )
{
if ( ( angXY > angTmp ) & & ( count ! = params . MaxStripes ) )
{
angXY = angXY + params . AngStart ;
angMem = angMem + params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
angTmp + = params . AngStripes ;
count + + ;
}
else
{
angXY = angXY - params . AngStart ;
angMem = angMem - params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
angTmp - = params . AngStripes ;
count - - ;
}
}
if ( ( ( count & 1 ) = = 1 ) & & ( params . RatioStripes > 1 ) )
{
if ( ( angXY > angTmp ) & & ( count ! = params . MaxStripes ) )
{
angMem = angMem - angXY + angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
angXY = angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
}
else
{
angMem = angMem - angXY + angTmp - ( angTmp - angXY ) / params . AngStart * params . RatioStripes * params . AngStart ;
angXY = angTmp + ( angXY - angTmp ) / params . AngStart * params . RatioStripes * params . AngStart ;
sincos ( angMem , & params . X , & params . Y ) ;
}
}
if ( ( ( count & 1 ) = = 1 ) & & ( params . RatioStripes < 1 ) )
{
if ( ( std : : abs ( angXY - angTmp ) > params . SpeedCalc2 ) & & ( count ! = params . MaxStripes ) )
{
if ( ( angXY - angTmp ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angXY - ( angTmp + params . SpeedCalc2 ) ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp + ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp + ratioTmp ;
}
if ( ( angTmp - angXY ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angTmp - params . SpeedCalc2 - angXY ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp - ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp - ratioTmp ;
}
}
if ( count = = params . MaxStripes )
{
angTmp = params . MidAngle ;
if ( ( angTmp - angXY ) > params . SpeedCalc2 )
{
ratioTmpNum = ( angTmp - params . SpeedCalc2 - angXY ) * params . SpeedCalc2 ;
ratioTmpDen = params . AngStart - params . SpeedCalc2 ;
ratioTmp = ratioTmpNum / ratioTmpDen ;
x = angMem - angXY + angTmp - ratioTmp ;
sincos ( x , & params . X , & params . Y ) ;
angXY = angTmp - ratioTmp ;
}
}
}
std : : swap ( params . RatioStripes , params . RatioComplement ) ;
std : : swap ( params . SpeedCalc1 , params . SpeedCalc2 ) ;
}
}
xTmp = params . Tan90M2 / ( params . Tan90M2 - std : : tan ( angXY ) ) ;
yTmp = xTmp * std : : tan ( angXY ) ;
params . LenOuterEdges = std : : sqrt ( SQR ( xTmp ) + SQR ( yTmp ) ) ;
if ( params . ExactCalc = = 1 )
{
if ( params . EqualBlur = = 1 )
ranTmp = std : : sqrt ( rand . Frand01 < T > ( ) ) ;
else
ranTmp = rand . Frand01 < T > ( ) ;
}
else
{
if ( params . CircumCircle = = 1 )
{
if ( params . EqualBlur = = 1 )
ranTmp = std : : sqrt ( rand . Frand01 < T > ( ) ) ;
else
ranTmp = rand . Frand01 < T > ( ) ;
}
else
{
if ( params . EqualBlur = = 1 )
ranTmp = std : : sqrt ( rand . Frand01 < T > ( ) ) * params . LenOuterEdges ;
else
ranTmp = rand . Frand01 < T > ( ) * params . LenOuterEdges ;
}
}
params . LenInnerEdges = params . RatioHole * params . LenOuterEdges ;
if ( params . ExactCalc = = 0 )
{
if ( ranTmp < params . LenInnerEdges )
{
if ( params . CircumCircle = = 1 )
{
if ( params . EqualBlur = = 1 )
ranTmp = params . LenInnerEdges + std : : sqrt ( rand . Frand01 < T > ( ) ) * ( 1 - params . LenInnerEdges + EPS ) ;
else
ranTmp = params . LenInnerEdges + rand . Frand01 < T > ( ) * ( 1 - params . LenInnerEdges + EPS ) ;
}
else
{
if ( params . EqualBlur = = 1 )
ranTmp = params . LenInnerEdges + std : : sqrt ( rand . Frand01 < T > ( ) ) * ( params . LenOuterEdges - params . LenInnerEdges ) ;
else
ranTmp = params . LenInnerEdges + rand . Frand01 < T > ( ) * ( params . LenOuterEdges - params . LenInnerEdges ) ;
}
}
}
params . X * = ranTmp ;
params . Y * = ranTmp ;
params . LenXY = std : : sqrt ( SQR ( params . X ) + SQR ( params . Y ) ) ;
}
T m_NumEdges ;
T m_NumStripes ;
T m_RatioStripes ;
T m_RatioHole ;
T m_CircumCircle ;
T m_AdjustToLinear ;
T m_EqualBlur ;
T m_ExactCalc ;
T m_HighlightEdges ;
T m_RatioComplement ; //Precalc.
T m_MidAngle ;
T m_AngStart ;
T m_AngStripes ;
T m_HasStripes ;
T m_NegStripes ;
T m_MaxStripes ;
T m_AbsStripes ;
T m_Sina ;
T m_Cosa ;
T m_Tan90M2 ;
T m_ArcTan1 ;
T m_ArcTan2 ;
T m_SpeedCalc1 ;
T m_SpeedCalc2 ;
T m_AdjustedWeight ;
} ;
/// <summary>
/// octapol.
/// </summary>
template < typename T >
class OctapolVariation : public ParametricVariation < T >
{
public :
OctapolVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " octapol " , eVariationId : : VAR_OCTAPOL , weight )
{
Init ( ) ;
}
PARVARCOPY ( OctapolVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
bool clear = false ;
T x = helper . In . x * T ( 0.15 ) , y = helper . In . y * T ( 0.15 ) , z = helper . In . z , r = 0 , u = 0 , v = 0 ;
v2T xy = { x , y } ;
v2T tempOut = { 0 , 0 } ;
if ( ( m_TempRad > 0 ) & & HitsCircleAroundOrigin ( m_TempRad , xy , r ) )
{
T rd = std : : log ( Sqr ( r / m_TempRad ) ) ;
T phi = std : : atan2 ( y , x ) ;
tempOut . x = m_Weight * Lerp ( x , phi , rd * m_Polarweight ) ;
tempOut . y = m_Weight * Lerp ( y , r , rd * m_Polarweight ) ;
}
else if ( HitsSquareAroundOrigin ( m_St , xy ) )
{
if ( HitsRect ( m_H , m_K , xy ) | | HitsRect ( m_J , m_D , xy ) | |
HitsRect ( m_A , m_J , xy ) | | HitsRect ( m_K , m_E , xy ) | |
HitsTriangle ( m_I , m_A , m_H , xy , u , v ) | |
HitsTriangle ( m_J , m_B , m_C , xy , u , v ) | |
HitsTriangle ( m_L , m_D , m_E , xy , u , v ) | |
HitsTriangle ( m_K , m_F , m_G , xy , u , v ) )
{
tempOut . x = m_Weight * x ;
tempOut . y = m_Weight * y ;
}
else
clear = true ;
}
else
clear = true ;
if ( clear )
{
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
helper . m_TransX = 0 ;
helper . m_TransY = 0 ;
}
else
{
outPoint . m_X = 0 ;
outPoint . m_Y = 0 ;
}
}
helper . Out . x = tempOut . x + ( m_Weight * x ) ;
helper . Out . y = tempOut . 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 weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string stateIndex = ss2 . str ( ) ;
string polarweight = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string radius = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string t = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string tempRad = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string abss = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string abst = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string st = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string axStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string bxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string cxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string dxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string exStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string fxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string gxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string hxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string ixStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string jxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string kxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ; i + = 2 ;
string lxStartIndex = ToUpper ( m_Params [ i ] . Name ( ) ) + stateIndex ;
ss < < " \t { \n "
< < " \t \t bool clear = false; \n "
< < " \t \t real_t x = vIn.x * 0.15, y = vIn.y * 0.15, z = vIn.z, r = 0, u = 0, v = 0, x2 = 0, y2 = 0; \n "
< < " \t \t real2 xy = { x, y }; \n "
< < " \t \t real2 tempOut = { 0, 0 }; \n "
< < " \t \t real2 A = { parVars[ " < < axStartIndex < < " ], parVars[ " < < axStartIndex < < " + 1] }; \n "
< < " \t \t real2 B = { parVars[ " < < bxStartIndex < < " ], parVars[ " < < bxStartIndex < < " + 1] }; \n "
< < " \t \t real2 C = { parVars[ " < < cxStartIndex < < " ], parVars[ " < < cxStartIndex < < " + 1] }; \n "
< < " \t \t real2 D = { parVars[ " < < dxStartIndex < < " ], parVars[ " < < dxStartIndex < < " + 1] }; \n "
< < " \t \t real2 E = { parVars[ " < < exStartIndex < < " ], parVars[ " < < exStartIndex < < " + 1] }; \n "
< < " \t \t real2 F = { parVars[ " < < fxStartIndex < < " ], parVars[ " < < fxStartIndex < < " + 1] }; \n "
< < " \t \t real2 G = { parVars[ " < < gxStartIndex < < " ], parVars[ " < < gxStartIndex < < " + 1] }; \n "
< < " \t \t real2 H = { parVars[ " < < hxStartIndex < < " ], parVars[ " < < hxStartIndex < < " + 1] }; \n "
< < " \t \t real2 I = { parVars[ " < < ixStartIndex < < " ], parVars[ " < < ixStartIndex < < " + 1] }; \n "
< < " \t \t real2 J = { parVars[ " < < jxStartIndex < < " ], parVars[ " < < jxStartIndex < < " + 1] }; \n "
< < " \t \t real2 K = { parVars[ " < < kxStartIndex < < " ], parVars[ " < < kxStartIndex < < " + 1] }; \n "
< < " \t \t real2 L = { parVars[ " < < lxStartIndex < < " ], parVars[ " < < lxStartIndex < < " + 1] }; \n "
< < " \n "
< < " \t \t if (( " < < tempRad < < " > 0) && HitsCircleAroundOrigin( " < < tempRad < < " , &xy, &r)) \n "
< < " \t \t { \n "
< < " \t \t real_t rd = log(Sqr(r / " < < tempRad < < " )); \n "
< < " \t \t real_t phi = atan2(y, x); \n "
< < " \n "
< < " \t \t tempOut.x = " < < weight < < " * Lerp(x, phi, rd * " < < polarweight < < " ); \n "
< < " \t \t tempOut.y = " < < weight < < " * Lerp(y, r, rd * " < < polarweight < < " ); \n "
< < " \t \t } \n "
< < " \t \t else if (HitsSquareAroundOrigin( " < < st < < " , &xy)) \n "
< < " \t \t { \n "
< < " \t \t if (HitsRect(&H, &K, &xy) || HitsRect(&J, &D, &xy) || \n "
< < " \t \t HitsRect(&A, &J, &xy) || HitsRect(&K, &E, &xy) || \n "
< < " \t \t HitsTriangle(&I, &A, &H, &xy, &u, &v) || \n "
< < " \t \t HitsTriangle(&J, &B, &C, &xy, &u, &v) || \n "
< < " \t \t HitsTriangle(&L, &D, &E, &xy, &u, &v) || \n "
< < " \t \t HitsTriangle(&K, &F, &G, &xy, &u, &v)) \n "
< < " \t \t { \n "
< < " \t \t tempOut.x = " < < weight < < " * x; \n "
< < " \t \t tempOut.y = " < < weight < < " * y; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t clear = true; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t clear = true; \n "
< < " \n "
< < " \t \t if (clear) \n "
< < " \t \t { \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_PRE )
{
ss
< < " \t \t transX = 0; \n "
< < " \t \t transY = 0; \n " ;
}
else
{
ss
< < " \t \t outPoint->m_X = 0; \n "
< < " \t \t outPoint->m_Y = 0; \n " ;
}
ss
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = fma( " < < weight < < " , x, tempOut.x); \n "
< < " \t \t vOut.y = fma( " < < weight < < " , y, tempOut.y); \n "
< < " \t \t vOut.z = " < < weight < < " * z; \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Lerp " , " Sqr " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" static int HitsRect(real2* tl, real2* br, real2* p) \n "
" { \n "
" return ((*p).x >= (*tl).x && (*p).y >= (*tl).y && (*p).x <= (*br).x && (*p).y <= (*br).y); \n "
" } \n "
" \n "
" static int HitsSquareAroundOrigin(real_t a, real2* p) \n "
" { \n "
" return (fabs((*p).x) <= a && fabs((*p).y) <= a); \n "
" } \n "
" \n "
" static int HitsCircleAroundOrigin(real_t radius, real2* p, real_t* r) \n "
" { \n "
" if (radius == 0) \n "
" return 1; \n "
" \n "
" *r = sqrt(fma((*p).x, (*p).x, SQR((*p).y))); \n "
" return (*r <= radius); \n "
" } \n "
" \n "
" static int HitsTriangle(real2* a, real2* b, real2* c, real2* p, real_t* u, real_t* v) \n "
" { \n "
" real2 v0 = { (*c).x - (*a).x, (*c).y - (*a).y }; \n "
" real2 v1 = { (*b).x - (*a).x, (*b).y - (*a).y }; \n "
" real2 v2 = { (*p).x - (*a).x, (*p).y - (*a).y }; \n "
" real_t d00 = dot(v0, v0); \n "
" real_t d01 = dot(v0, v1); \n "
" real_t d02 = dot(v0, v2); \n "
" real_t d11 = dot(v1, v1); \n "
" real_t d12 = dot(v1, v2); \n "
" real_t denom = fma(d00, d11, -(d01 * d01)); \n "
" \n "
" if (denom != 0) \n "
" { \n "
" *u = fma(d11, d02, -(d01 * d12)) / denom; \n "
" *v = fma(d00, d12, -(d01 * d02)) / denom; \n "
" } \n "
" else \n "
" *u = *v = 0; \n "
" \n "
" return ((*u + *v) < 1) && (*u > 0) && (*v > 0); \n "
" } \n \n " ;
}
virtual void Precalc ( ) override
{
static const T DENOM_SQRT2 = T ( 0.707106781 ) ;
m_AbsS = std : : abs ( m_S ) ;
m_AbsT = std : : abs ( m_T ) ;
m_St = m_AbsS * T ( 0.5 ) + m_AbsT ;
m_TempRad = DENOM_SQRT2 * m_AbsS * std : : abs ( m_Radius ) ;
m_A = { - T ( 0.5 ) * m_AbsS , T ( 0.5 ) * m_AbsS + m_AbsT } ;
m_B = { T ( 0.5 ) * m_AbsS , T ( 0.5 ) * m_AbsS + m_AbsT } ;
m_C = { m_AbsT , T ( 0.5 ) * m_AbsS } ;
m_D = { m_AbsT , - T ( 0.5 ) * m_AbsS } ;
m_E = { T ( 0.5 ) * m_AbsS , - T ( 0.5 ) * m_AbsS - m_AbsT } ;
m_F = { - T ( 0.5 ) * m_AbsS , - T ( 0.5 ) * m_AbsS - m_AbsT } ;
m_G = { - m_AbsT , - T ( 0.5 ) * m_AbsS } ;
m_H = { - m_AbsT , T ( 0.5 ) * m_AbsS } ;
m_I = { - T ( 0.5 ) * m_AbsS , T ( 0.5 ) * m_AbsS } ;
m_J = { T ( 0.5 ) * m_AbsS , T ( 0.5 ) * m_AbsS } ;
m_K = { - T ( 0.5 ) * m_AbsS , - T ( 0.5 ) * m_AbsS } ;
m_L = { T ( 0.5 ) * m_AbsS , - T ( 0.5 ) * m_AbsS } ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Polarweight , prefix + " octapol_polarweight " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Radius , prefix + " octapol_radius " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_S , prefix + " octapol_s " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_T , prefix + " octapol_t " , T ( 0.5 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_TempRad , prefix + " octapol_rad " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsS , prefix + " octapol_abss " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsT , prefix + " octapol_abst " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_St , prefix + " octapol_absst " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_A . x , prefix + " octapol_ax " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_A . y , prefix + " octapol_ay " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_B . x , prefix + " octapol_bx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_B . y , prefix + " octapol_by " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_C . x , prefix + " octapol_cx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_C . y , prefix + " octapol_cy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_D . x , prefix + " octapol_dx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_D . y , prefix + " octapol_dy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_E . x , prefix + " octapol_ex " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_E . y , prefix + " octapol_ey " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_F . x , prefix + " octapol_fx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_F . y , prefix + " octapol_fy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_G . x , prefix + " octapol_gx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_G . y , prefix + " octapol_gy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_H . x , prefix + " octapol_hx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_H . y , prefix + " octapol_hy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_I . x , prefix + " octapol_ix " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_I . y , prefix + " octapol_iy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_J . x , prefix + " octapol_jx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_J . y , prefix + " octapol_jy " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_K . x , prefix + " octapol_kx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_K . y , prefix + " octapol_ky " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_L . x , prefix + " octapol_lx " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_L . y , prefix + " octapol_ly " ) ) ;
}
private :
int HitsRect ( v2T & tl , v2T & br , v2T & p )
{
return ( p . x > = tl . x & & p . y > = tl . y & & p . x < = br . x & & p . y < = br . y ) ;
}
int HitsSquareAroundOrigin ( T a , v2T & p )
{
return ( std : : abs ( p . x ) < = a & & std : : abs ( p . y ) < = a ) ;
}
int HitsCircleAroundOrigin ( T radius , v2T & p , T & r )
{
if ( radius = = 0 )
return 1 ;
r = std : : sqrt ( SQR ( p . x ) + SQR ( p . y ) ) ;
return ( r < = radius ) ;
}
int HitsTriangle ( v2T & a , v2T & b , v2T & c , v2T & p , T & u , T & v )
{
v2T v0 = { c . x - a . x , c . y - a . y } ;
v2T v1 = { b . x - a . x , b . y - a . y } ;
v2T v2 = { p . x - a . x , p . y - a . y } ;
T d00 = glm : : dot ( v0 , v0 ) ;
T d01 = glm : : dot ( v0 , v1 ) ;
T d02 = glm : : dot ( v0 , v2 ) ;
T d11 = glm : : dot ( v1 , v1 ) ;
T d12 = glm : : dot ( v1 , v2 ) ;
T denom = ( d00 * d11 - d01 * d01 ) ;
if ( denom ! = 0 )
{
u = ( d11 * d02 - d01 * d12 ) / denom ;
v = ( d00 * d12 - d01 * d02 ) / denom ;
}
else
u = v = 0 ;
return ( ( u + v ) < 1 ) & & ( u > 0 ) & & ( v > 0 ) ;
}
T m_Polarweight ;
T m_Radius ;
T m_S ;
T m_T ;
T m_TempRad ; //Precalc.
T m_AbsS ;
T m_AbsT ;
T m_St ;
v2T m_A ;
v2T m_B ;
v2T m_C ;
v2T m_D ;
v2T m_E ;
v2T m_F ;
v2T m_G ;
v2T m_H ;
v2T m_I ;
v2T m_J ;
v2T m_K ;
v2T m_L ;
} ;
/// <summary>
/// crob.
/// This uses the input point in an extremely rare way since it changes it.
/// </summary>
template < typename T >
class CrobVariation : public ParametricVariation < T >
{
public :
CrobVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " crob " , eVariationId : : VAR_CROB , weight )
{
Init ( ) ;
}
PARVARCOPY ( CrobVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T gradTmp , secTmp , xTmp = 0 , yTmp = 0 ;
if ( ( helper . In . x < m_LeftBorder ) | | ( helper . In . x > m_RightBorder ) | | ( helper . In . y < m_TopBorder ) | | ( helper . In . y > m_BottomBorder ) )
{
if ( m_Blur = = 0 )
{
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
helper . In . x = helper . m_TransX = 0 ; //This will not only overwrite the current output point running sum, but also set
helper . In . y = helper . m_TransY = 0 ; //the affine transformed point so that any future variation that uses it directly will get the updated value.
}
}
else
{
secTmp = rand . Frand01 < T > ( ) ;
if ( secTmp < m_SetProb )
{
do
{
yTmp = m_Top + rand . Frand01 < T > ( ) * m_YInt2 ;
xTmp = m_Right - pow ( rand . Frand01 < T > ( ) , m_DirectBlur ) * m_RatioBlur * m_MinInt2 ;
}
while ( ( yTmp - m_Y0c ) / Zeps ( xTmp - m_X0c ) < - 1 ) ;
if ( secTmp < m_SetProbH )
xTmp = m_Left + m_Right - xTmp ;
if ( ( secTmp > m_SetProbQ ) & & ( secTmp < m_SetProbTQ ) )
yTmp = m_Bottom + m_Top - yTmp ;
}
else
{
do
{
xTmp = m_Right - rand . Frand01 < T > ( ) * m_XInt2 ;
yTmp = m_Top + std : : pow ( rand . Frand01 < T > ( ) , m_DirectBlur ) * m_RatioBlur * m_MinInt2 ;
gradTmp = ( yTmp - m_Y0c ) / Zeps ( xTmp - m_X0c ) ;
}
while ( ( gradTmp < = 0 ) & & ( gradTmp > - 1 ) ) ;
if ( secTmp > m_SetProbH )
yTmp = m_Bottom + m_Top - yTmp ;
if ( ( secTmp > m_SetProbQ ) & & ( secTmp < m_SetProbTQ ) )
xTmp = m_Left + m_Right - xTmp ;
}
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
helper . In . x = helper . m_TransX = xTmp ; //This will not only overwrite the current output point running sum, but also set
helper . In . y = helper . m_TransY = yTmp ; //the affine transformed point so that any future variation that uses it directly will get the updated value.
}
}
}
helper . Out . x = xTmp ;
helper . Out . y = yTmp ;
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 top = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string bottom = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string left = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string right = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string blur = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ratioBlur = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string directBlur = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string xInterval = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string yInterval = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string xInt2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string yInt2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string minInt2 = " 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 x0c = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string y0c = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setProb = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setProbH = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setProbQ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setProbTQ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setCompProb = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setCompProbH = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setCompProbQ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string setCompProbTQ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string topBorder = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string bottomBorder = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string leftBorder = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rightBorder = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t gradTmp, secTmp, xTmp = 0, yTmp = 0; \n "
< < " \n "
< < " \t \t if ((vIn.x < " < < leftBorder < < " ) || (vIn.x > " < < rightBorder < < " ) || (vIn.y < " < < topBorder < < " ) || (vIn.y > " < < bottomBorder < < " )) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < blur < < " == 0) \n "
< < " \t \t { \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
ss
< < " \t \t vIn.x = transX = 0; \n "
< < " \t \t vIn.y = transY = 0; \n " ;
}
ss
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t secTmp = MwcNext01(mwc); \n "
< < " \n "
< < " \t \t if (secTmp < " < < setProb < < " ) \n "
< < " \t \t { \n "
< < " \t \t do \n "
< < " \t \t { \n "
< < " \t \t yTmp = fma(MwcNext01(mwc), " < < yInt2 < < " , " < < top < < " ); \n "
< < " \t \t xTmp = " < < right < < " - pow(MwcNext01(mwc), " < < directBlur < < " ) * " < < ratioBlur < < " * " < < minInt2 < < " ; \n "
< < " \t \t } while ((yTmp - " < < y0c < < " ) / Zeps(xTmp - " < < x0c < < " ) < -1); \n "
< < " \n "
< < " \t \t if (secTmp < " < < setProbH < < " ) \n "
< < " \t \t xTmp = " < < left < < " + " < < right < < " - xTmp; \n "
< < " \n "
< < " \t \t if ((secTmp > " < < setProbQ < < " ) && (secTmp < " < < setProbTQ < < " )) \n "
< < " \t \t yTmp = " < < bottom < < " + " < < top < < " - yTmp; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t do \n "
< < " \t \t { \n "
< < " \t \t xTmp = " < < right < < " - MwcNext01(mwc) * " < < xInt2 < < " ; \n "
< < " \t \t yTmp = " < < top < < " + pow(MwcNext01(mwc), " < < directBlur < < " ) * " < < ratioBlur < < " * " < < minInt2 < < " ; \n "
< < " \t \t gradTmp = (yTmp - " < < y0c < < " ) / Zeps(xTmp - " < < x0c < < " ); \n "
< < " \t \t } while ((gradTmp <= 0) && (gradTmp > -1)); \n "
< < " \n "
< < " \t \t if (secTmp > " < < setProbH < < " ) \n "
< < " \t \t yTmp = " < < bottom < < " + " < < top < < " - yTmp; \n "
< < " \n "
< < " \t \t if ((secTmp > " < < setProbQ < < " ) && (secTmp < " < < setProbTQ < < " )) \n "
< < " \t \t xTmp = " < < left < < " + " < < right < < " - xTmp; \n "
< < " \t \t } \n "
< < " \n " ;
if ( m_VarType = = eVariationType : : VARTYPE_REG )
{
ss
< < " \t \t vIn.x = transX = xTmp; \n "
< < " \t \t vIn.y = transY = yTmp; \n " ;
}
ss
< < " \t \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.x = xTmp; \n "
< < " \t \t vOut.y = yTmp; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
if ( m_Top > m_Bottom )
std : : swap ( m_Top , m_Bottom ) ;
if ( m_Top = = m_Bottom )
{
m_Top = - 1 ;
m_Bottom = 1 ;
}
if ( m_Left > m_Right )
std : : swap ( m_Left , m_Right ) ;
if ( m_Left = = m_Right )
{
m_Left = - 1 ;
m_Right = 1 ;
}
if ( m_DirectBlur < 0 )
m_DirectBlur = 0 ;
if ( m_Blur ! = 0 )
m_Blur = 1 ;
m_XInterval = std : : abs ( m_Right ) - m_Left ;
m_YInterval = std : : abs ( m_Bottom ) - m_Top ;
m_XInt2 = m_XInterval / 2 ;
m_YInt2 = m_YInterval / 2 ;
if ( m_XInt2 > m_YInt2 )
m_MinInt2 = m_YInt2 ;
else
m_MinInt2 = m_XInt2 ;
m_X0 = m_Right - m_XInt2 ;
m_Y0 = m_Top + m_YInt2 ;
if ( m_XInt2 > m_YInt2 )
{
m_X0c = m_Right - m_MinInt2 ;
m_Y0c = m_Y0 ;
}
else if ( m_XInt2 < m_YInt2 )
{
m_X0c = m_X0 ;
m_Y0c = m_Top + m_MinInt2 ;
}
else
{
m_X0c = m_X0 ;
m_Y0c = m_Y0 ;
}
m_SetProb = m_YInterval / ( m_XInterval + m_YInterval ) ;
m_SetProbQ = T ( 0.25 ) * m_SetProb ;
m_SetProbH = T ( 0.50 ) * m_SetProb ;
m_SetProbTQ = T ( 0.75 ) * m_SetProb ;
m_SetCompProb = T ( 1.0 ) - m_SetProb ;
m_SetCompProbQ = m_SetProb + T ( 0.25 ) * m_SetCompProb ;
m_SetCompProbH = m_SetProb + T ( 0.50 ) * m_SetCompProb ;
m_SetCompProbTQ = m_SetProb + T ( 0.75 ) * m_SetCompProb ;
if ( m_Blur = = 0 )
{
m_TopBorder = m_Top ;
m_BottomBorder = m_Bottom ;
m_LeftBorder = m_Left ;
m_RightBorder = m_Right ;
}
else
{
m_TopBorder = m_Top + m_MinInt2 * m_RatioBlur ;
m_BottomBorder = m_Bottom - m_MinInt2 * m_RatioBlur ;
m_LeftBorder = m_Left + m_MinInt2 * m_RatioBlur ;
m_RightBorder = m_Right - m_MinInt2 * m_RatioBlur ;
}
}
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_Top , prefix + " crob_top " , - 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Bottom , prefix + " crob_bottom " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Left , prefix + " crob_left " , - 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Right , prefix + " crob_right " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Blur , prefix + " crob_blur " , 1 , eParamType : : INTEGER ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_RatioBlur , prefix + " crob_ratioBlur " , T ( 0.5 ) , eParamType : : REAL , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_DirectBlur , prefix + " crob_directBlur " , 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
m_Params . push_back ( ParamWithName < T > ( true , & m_XInterval , prefix + " crob_xinterval " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_YInterval , prefix + " crob_yinterval " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_XInt2 , prefix + " crob_xint2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_YInt2 , prefix + " crob_yint2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_MinInt2 , prefix + " crob_minint2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_X0 , prefix + " crob_x0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Y0 , prefix + " crob_y0 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_X0c , prefix + " crob_x0c " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Y0c , prefix + " crob_y0c " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetProb , prefix + " crob_set_prob " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetProbH , prefix + " crob_set_prob_h " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetProbQ , prefix + " crob_set_prob_q " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetProbTQ , prefix + " crob_set_prob_tq " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetCompProb , prefix + " crob_set_comp_prob " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetCompProbH , prefix + " crob_set_comp_prob_h " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetCompProbQ , prefix + " crob_set_comp_prob_q " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SetCompProbTQ , prefix + " crob_set_comp_prob_tq " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_TopBorder , prefix + " crob_top_border " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_BottomBorder , prefix + " crob_bottom_border " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_LeftBorder , prefix + " crob_left_border " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RightBorder , prefix + " crob_right_border " ) ) ;
}
private :
T m_Top ;
T m_Bottom ;
T m_Left ;
T m_Right ;
T m_Blur ;
T m_RatioBlur ;
T m_DirectBlur ;
T m_XInterval ; //Precalc.
T m_YInterval ;
T m_XInt2 ;
T m_YInt2 ;
T m_MinInt2 ;
T m_X0 ;
T m_Y0 ;
T m_X0c ;
T m_Y0c ;
T m_SetProb ;
T m_SetProbH ;
T m_SetProbQ ;
T m_SetProbTQ ;
T m_SetCompProb ;
T m_SetCompProbH ;
T m_SetCompProbQ ;
T m_SetCompProbTQ ;
T m_TopBorder ;
T m_BottomBorder ;
T m_LeftBorder ;
T m_RightBorder ;
} ;
/// <summary>
/// bubbleT3D.
/// </summary>
template < typename T >
class BubbleT3DVariation : public ParametricVariation < T >
{
public :
BubbleT3DVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " bubbleT3D " , eVariationId : : VAR_BUBBLET3D , weight , true )
{
Init ( ) ;
}
PARVARCOPY ( BubbleT3DVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T x = helper . In . x , y = helper . In . y , z = helper . In . z ;
T xTmp , yTmp , angTmp , angRot , fac ;
T rad = Zeps < T > ( helper . m_PrecalcSumSquares / 4 + 1 ) ;
T angXY , angZ ;
T c , s ;
angXY = std : : atan2 ( x , y ) ;
if ( angXY < 0 )
angXY + = M_2PI ;
if ( m_AbsNumberStripes ! = 0 )
{
while ( angXY > m_AngStrip2 )
{
angXY - = m_AngStrip2 ;
}
if ( m_InvStripes = = 0 )
{
if ( angXY > m_AngStrip1 )
{
if ( m_ModusBlur = = 0 )
{
x = 0 ;
y = 0 ;
}
else
{
if ( m_RatioStripes = = 1 )
{
xTmp = m_C * x - m_S * y ;
yTmp = m_S * x + m_C * y ;
x = xTmp ;
y = yTmp ;
}
else
{
angRot = ( angXY - m_AngStrip1 ) / Zeps < T > ( m_AngStrip2 - m_AngStrip1 ) ;
angRot = angXY - angRot * m_AngStrip1 ;
sincos ( angRot , & s , & c ) ;
xTmp = c * x - s * y ;
yTmp = s * x + c * y ;
x = xTmp ;
y = yTmp ;
}
}
}
}
else
{
if ( angXY < m_AngStrip1 )
{
if ( m_ModusBlur = = 0 )
{
x = 0 ;
y = 0 ;
}
else
{
if ( m_AbsNumberStripes = = 1 )
{
xTmp = m_C * x - m_S * y ;
yTmp = m_S * x + m_C * y ;
x = xTmp ;
y = yTmp ;
}
else
{
angRot = ( angXY - m_AngStrip1 ) / m_AngStrip1 ;
angRot = angXY - angRot * ( m_AngStrip2 - m_AngStrip1 ) ;
sincos ( angRot , & s , & c ) ;
xTmp = c * x - s * y ;
yTmp = s * x + c * y ;
x = xTmp ;
y = yTmp ;
}
}
}
}
}
x = x / rad ;
y = y / rad ;
if ( ( x ! = 0 ) | | ( y ! = 0 ) )
{
z = 2 / std : : pow ( rad , m_ExponentZ ) - 1 ;
if ( m_ExponentZ < = 2 )
angZ = T ( M_PI ) - std : : acos ( ( z / ( SQR ( x ) + SQR ( y ) + SQR ( z ) ) ) ) ;
else
angZ = T ( M_PI ) - std : : atan2 ( Sqr ( SQR ( x ) + SQR ( y ) ) , z ) ;
}
else
{
z = 0 ;
angZ = 0 ;
}
if ( m_SymmetryZ = = 0 )
{
if ( m_InvHole = = 0 )
{
if ( angZ > m_AngleHoleTemp )
{
if ( ( m_ModusBlur = = 0 ) | | ( m_ExponentZ ! = 1 ) )
{
x = 0 ;
y = 0 ;
z = 0 ;
}
else
{
angTmp = ( T ( M_PI ) - angZ ) / Zeps < T > ( m_AngHoleComp * m_AngleHoleTemp - T ( M_PI_2 ) ) ;
angZ - = T ( M_PI_2 ) ;
fac = std : : cos ( angTmp ) / std : : cos ( angZ ) ;
x * = fac ;
y * = fac ;
z * = ( std : : sin ( angTmp ) / std : : sin ( angZ ) ) ;
}
}
}
else
{
if ( angZ < m_AngleHoleTemp )
{
if ( ( m_ModusBlur = = 0 ) | | ( m_ExponentZ ! = 1 ) )
{
x = 0 ;
y = 0 ;
z = 0 ;
}
else
{
angTmp = T ( M_PI ) - angZ / Zeps < T > ( m_AngHoleComp * m_AngleHoleTemp - T ( M_PI_2 ) ) ;
angZ - = T ( M_PI_2 ) ;
fac = std : : cos ( angTmp ) / std : : cos ( angZ ) ;
x * = fac ;
y * = fac ;
z * = ( std : : sin ( angTmp ) / std : : sin ( angZ ) ) ;
}
}
}
}
else
{
if ( ( angZ > m_AngleHoleTemp ) | | ( angZ < ( T ( M_PI ) - m_AngleHoleTemp ) ) )
{
if ( ( m_ModusBlur = = 0 ) | | ( m_ExponentZ ! = 1 ) )
{
x = 0 ;
y = 0 ;
z = 0 ;
}
else
{
if ( angZ > m_AngleHoleTemp )
angTmp = ( T ( M_PI ) - angZ ) / m_AngHoleComp * ( T ( M_PI ) - 2 * m_AngHoleComp ) + m_AngHoleComp - T ( M_PI_2 ) ;
else
angTmp = T ( M_PI_2 ) - ( angZ / m_AngHoleComp * ( T ( M_PI ) - 2 * m_AngHoleComp ) + m_AngHoleComp ) ;
angZ - = T ( M_PI_2 ) ;
fac = std : : cos ( angTmp ) / std : : cos ( angZ ) ;
x * = fac ;
y * = fac ;
z * = ( std : : sin ( angTmp ) / std : : sin ( angZ ) ) ;
}
}
}
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 weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string numberStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string ratioStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angleHole = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string exponentZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string symmetryZ = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string modusBlur = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string absNumberStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angHoleTemp = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angStrip = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angStrip1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angStrip2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invStripes = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string angHoleComp = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invHole = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string c = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string s = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
" \t \t real_t x = vIn.x, y = vIn.y, z = vIn.z; \n "
" \t \t real_t xTmp, yTmp, angTmp, angRot, fac; \n "
" \t \t real_t rad = Zeps(precalcSumSquares / 4 + 1); \n "
" \t \t real_t angXY, angZ; \n "
" \t \t real_t c, s; \n "
" \t \t \n "
" \t \t angXY = atan2(x, y); \n "
" \t \t \n "
" \t \t if (angXY < 0) \n "
" \t \t angXY += M_2PI; \n "
" \t \t \n "
" \t \t if ( " < < absNumberStripes < < " != 0) \n "
" \t \t { \n "
" \t \t while (angXY > " < < angStrip2 < < " ) \n "
" \t \t { \n "
" \t \t angXY -= " < < angStrip2 < < " ; \n "
" \t \t } \n "
" \t \t \n "
" \t \t if ( " < < invStripes < < " == 0) \n "
" \t \t { \n "
" \t \t if (angXY > " < < angStrip1 < < " ) \n "
" \t \t { \n "
" \t \t if ( " < < modusBlur < < " == 0) \n "
" \t \t { \n "
" \t \t x = 0; \n "
" \t \t y = 0; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if ( " < < ratioStripes < < " == 1) \n "
" \t \t { \n "
" \t \t xTmp = fma( " < < c < < " , x, -( " < < s < < " * y)); \n "
" \t \t yTmp = fma( " < < s < < " , x, " < < c < < " * y); \n "
" \t \t x = xTmp; \n "
" \t \t y = yTmp; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t angRot = (angXY - " < < angStrip1 < < " ) / Zeps( " < < angStrip2 < < " - " < < angStrip1 < < " ); \n "
" \t \t angRot = angXY - angRot * " < < angStrip1 < < " ; \n "
" \t \t s = sincos(angRot, &c); \n "
" \t \t xTmp = fma(c, x, -(s * y)); \n "
" \t \t yTmp = fma(s, x, c * y); \n "
" \t \t x = xTmp; \n "
" \t \t y = yTmp; \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if (angXY < " < < angStrip1 < < " ) \n "
" \t \t { \n "
" \t \t if ( " < < modusBlur < < " == 0) \n "
" \t \t { \n "
" \t \t x = 0; \n "
" \t \t y = 0; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if ( " < < absNumberStripes < < " == 1) \n "
" \t \t { \n "
" \t \t xTmp = fma( " < < c < < " , x, -( " < < s < < " * y)); \n "
" \t \t yTmp = fma( " < < s < < " , x, " < < c < < " * y); \n "
" \t \t x = xTmp; \n "
" \t \t y = yTmp; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t angRot = (angXY - " < < angStrip1 < < " ) / " < < angStrip1 < < " ; \n "
" \t \t angRot = angXY - angRot * ( " < < angStrip2 < < " - " < < angStrip1 < < " ); \n "
" \t \t s = sincos(angRot, &c); \n "
" \t \t xTmp = fma(c, x, -(s * y)); \n "
" \t \t yTmp = fma(s, x, c * y); \n "
" \t \t x = xTmp; \n "
" \t \t y = yTmp; \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t \n "
" \t \t x = x / rad; \n "
" \t \t y = y / rad; \n "
" \t \t \n "
" \t \t if ((x != 0) || (y != 0)) \n "
" \t \t { \n "
" \t \t z = 2 / pow(rad, " < < exponentZ < < " ) - 1; \n "
" \t \t \n "
" \t \t if ( " < < exponentZ < < " <= 2) \n "
" \t \t angZ = MPI - acos((z / fma(x, x, fma(y, y, SQR(z))))); \n "
" \t \t else \n "
" \t \t angZ = MPI - atan2(Sqr(fma(x, x, SQR(y))), z); \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t z = 0; \n "
" \t \t angZ = 0; \n "
" \t \t } \n "
" \t \t \n "
" \t \t if ( " < < symmetryZ < < " == 0) \n "
" \t \t { \n "
" \t \t if ( " < < invHole < < " == 0) \n "
" \t \t { \n "
" \t \t if (angZ > " < < angHoleTemp < < " ) \n "
" \t \t { \n "
" \t \t if (( " < < modusBlur < < " == 0) || ( " < < exponentZ < < " != 1)) \n "
" \t \t { \n "
" \t \t x = 0; \n "
" \t \t y = 0; \n "
" \t \t z = 0; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t angTmp = (MPI - angZ) / Zeps(fma( " < < angHoleComp < < " , " < < angHoleTemp < < " , -MPI2)); \n "
" \t \t angZ -= MPI2; \n "
" \t \t fac = cos(angTmp) / cos(angZ); \n "
" \t \t x *= fac; \n "
" \t \t y *= fac; \n "
" \t \t z *= (sin(angTmp) / sin(angZ)); \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if (angZ < " < < angHoleTemp < < " ) \n "
" \t \t { \n "
" \t \t if (( " < < modusBlur < < " == 0) || ( " < < exponentZ < < " != 1)) \n "
" \t \t { \n "
" \t \t x = 0; \n "
" \t \t y = 0; \n "
" \t \t z = 0; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t angTmp = MPI - angZ / Zeps(fma( " < < angHoleComp < < " , " < < angHoleTemp < < " , -MPI2)); \n "
" \t \t angZ -= MPI2; \n "
" \t \t fac = cos(angTmp) / cos(angZ); \n "
" \t \t x *= fac; \n "
" \t \t y *= fac; \n "
" \t \t z *= (sin(angTmp) / sin(angZ)); \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if ((angZ > " < < angHoleTemp < < " ) || (angZ < (MPI - " < < angHoleTemp < < " ))) \n "
" \t \t { \n "
" \t \t if (( " < < modusBlur < < " == 0) || ( " < < exponentZ < < " != 1)) \n "
" \t \t { \n "
" \t \t x = 0; \n "
" \t \t y = 0; \n "
" \t \t z = 0; \n "
" \t \t } \n "
" \t \t else \n "
" \t \t { \n "
" \t \t if (angZ > " < < angHoleTemp < < " ) \n "
" \t \t angTmp = (MPI - angZ) / " < < angHoleComp < < " * (MPI - 2 * " < < angHoleComp < < " ) + " < < angHoleComp < < " - MPI2; \n "
" \t \t else \n "
" \t \t angTmp = MPI2 - (angZ / " < < angHoleComp < < " * (MPI - 2 * " < < angHoleComp < < " ) + " < < angHoleComp < < " ); \n "
" \n "
" \t \t angZ -= MPI2; \n "
" \t \t fac = cos(angTmp) / cos(angZ); \n "
" \t \t x *= fac; \n "
" \t \t y *= fac; \n "
" \t \t z *= (sin(angTmp) / sin(angZ)); \n "
" \t \t } \n "
" \t \t } \n "
" \t \t } \n "
" \t \t \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 ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " , " Zeps " } ;
}
virtual void Precalc ( ) override
{
if ( m_NumberStripes < 0 )
{
m_AbsNumberStripes = std : : abs ( m_NumberStripes ) ;
m_InvStripes = 1 ;
}
else
{
m_AbsNumberStripes = m_NumberStripes ;
m_InvStripes = 0 ;
}
if ( m_AbsNumberStripes ! = 0 )
{
m_AngStrip = T ( M_PI ) / m_AbsNumberStripes ;
m_AngStrip2 = 2 * m_AngStrip ;
sincos ( m_AngStrip , & m_S , & m_C ) ;
ClampRef < T > ( m_RatioStripes , T ( 0.01 ) , T ( 1.99 ) ) ;
m_AngStrip1 = Zeps < T > ( m_RatioStripes * m_AngStrip ) ;
}
if ( m_SymmetryZ = = 1 )
{
if ( m_AngleHole < 0 )
m_AngleHoleTemp = std : : abs ( m_AngleHole ) ;
else if ( m_AngleHole > T ( 179.9 ) )
m_AngleHoleTemp = T ( 179.9 ) ;
else
m_AngleHoleTemp = m_AngleHole ;
}
else
m_AngleHoleTemp = m_AngleHole ;
if ( m_AngleHoleTemp < 0 )
{
m_AngleHoleTemp = std : : abs ( m_AngleHole ) ;
m_InvHole = 1 ;
m_AngleHoleTemp = ( m_AngleHoleTemp / 360 * M_2PI ) / 2 ;
}
else
{
m_InvHole = 0 ;
m_AngleHoleTemp = T ( M_PI ) - ( m_AngleHoleTemp / 360 * M_2PI ) / 2 ;
}
m_AngHoleComp = T ( M_PI ) - m_AngleHoleTemp ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 14 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_NumberStripes , prefix + " bubbleT3D_number_of_stripes " , 0 , eParamType : : INTEGER ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_RatioStripes , prefix + " bubbleT3D_ratio_of_stripes " , 1 , eParamType : : REAL , 0 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_AngleHole , prefix + " bubbleT3D_angle_of_hole " , 0 , eParamType : : REAL , - 360 , 360 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ExponentZ , prefix + " bubbleT3D_exponentZ " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SymmetryZ , prefix + " bubbleT3D_symmetryZ " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_ModusBlur , prefix + " bubbleT3D_modusBlur " , 0 , eParamType : : INTEGER , 0 , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AbsNumberStripes , prefix + " bubbleT3D_abs_number_of_stripes " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_AngleHoleTemp , prefix + " bubbleT3D_ang_hole_temp " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngStrip , prefix + " bubbleT3D_ang_strip " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngStrip1 , prefix + " bubbleT3D_ang_strip1 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngStrip2 , prefix + " bubbleT3D_ang_strip2 " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_InvStripes , prefix + " bubbleT3D_inv_stripes " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_AngHoleComp , prefix + " bubbleT3D_ang_hole_comp " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_InvHole , prefix + " bubbleT3D_inv_hole " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_C , prefix + " bubbleT3D_c " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_S , prefix + " bubbleT3D_s " ) ) ;
}
private :
T m_NumberStripes ;
T m_RatioStripes ;
T m_AngleHole ;
T m_ExponentZ ;
T m_SymmetryZ ;
T m_ModusBlur ;
T m_AbsNumberStripes ; //Precalc.
T m_AngleHoleTemp ;
T m_AngStrip ;
T m_AngStrip1 ;
T m_AngStrip2 ;
T m_InvStripes ;
T m_AngHoleComp ;
T m_InvHole ;
T m_C ;
T m_S ;
} ;
// -------------------------------------------------------------
// Modes
// "Lagacy" modes from v1
# define MODE_SPHERICAL 0
# define MODE_BUBBLE 1
# define MODE_BLUR_LEGACY 2
// New modes in v2
# define MODE_BLUR_NEW 3
# define MODE_BLUR_ZIGZAG 4
# define MODE_RAWCIRCLE 5
# define MODE_RAWX 6
# define MODE_RAWY 7
# define MODE_RAWXY 8
# define MODE_SHIFTX 9
# define MODE_SHIFTY 10
# define MODE_SHIFTXY 11
# define MODE_SINUSOIDAL 12
# define MODE_SWIRL 13
# define MODE_HYPERBOLIC 14
# define MODE_JULIA 15
# define MODE_DISC 16
# define MODE_RINGS 17
# define MODE_CYLINDER 18
# define MODE_BLUR_RING 19
# define MODE_BLUR_RING2 20
# define MODE_SHIFTTHETA 21
# define MODE_SHIFTNSTRETCH 22
# define MODE_SHIFTTANGENT 23
# define MODE_XMIRROR 24
# define MODE_XYMIRROR 25
# define MODE_SPHERICAL2 26
// -------------------------------------------------------------
// Wave types
# define WAVE_SIN 0
# define WAVE_COS 1
# define WAVE_SQUARE 2
# define WAVE_SAW 3
# define WAVE_TRIANGLE 4
# define WAVE_CONCAVE 5
# define WAVE_CONVEX 6
# define WAVE_NGON 7
// New wave types in v2
# define WAVE_INGON 8
// -------------------------------------------------------------
// Layer types
# define LAYER_ADD 0
# define LAYER_MULT 1
# define LAYER_MAX 2
# define LAYER_MIN 3
// -------------------------------------------------------------
// Interpolation types
# define LERP_LINEAR 0
# define LERP_BEZIER 1
// -------------------------------------------------------------
// Sine/Cosine interpretation types
# define SINCOS_MULTIPLY 0
# define SINCOS_MIXIN 1
/// <summary>
/// synth.
/// </summary>
template < typename T >
class SynthVariation : public ParametricVariation < T >
{
public :
SynthVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " synth " , eVariationId : : VAR_SYNTH , weight , true , true , false , true )
{
Init ( ) ;
}
PARVARCOPY ( SynthVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T Vx , Vy , radius , theta ; // Position vector in cartesian and polar co-ords
T thetaFactor ; // Evaluation of synth() function for current point
T s , c , mu ; // Handy temp variables, s & c => sine & cosine, mu = generic temp param
int synthMode = int ( m_SynthMode ) ;
int synthSmooth = int ( m_SynthSmooth ) ;
SynthStruct synth ;
synth . SynthA = m_SynthA ;
synth . SynthB = m_SynthB ;
synth . SynthBPhs = m_SynthBPhs ;
synth . SynthBFrq = m_SynthBFrq ;
synth . SynthBSkew = m_SynthBSkew ;
synth . SynthBType = int ( m_SynthBType ) ;
synth . SynthBLayer = int ( m_SynthBLayer ) ;
synth . SynthC = m_SynthC ;
synth . SynthCPhs = m_SynthCPhs ;
synth . SynthCFrq = m_SynthCFrq ;
synth . SynthCSkew = m_SynthCSkew ;
synth . SynthCType = int ( m_SynthCType ) ;
synth . SynthCLayer = int ( m_SynthCLayer ) ;
synth . SynthD = m_SynthD ;
synth . SynthDPhs = m_SynthDPhs ;
synth . SynthDFrq = m_SynthDFrq ;
synth . SynthDSkew = m_SynthDSkew ;
synth . SynthDType = int ( m_SynthDType ) ;
synth . SynthDLayer = int ( m_SynthDLayer ) ;
synth . SynthE = m_SynthE ;
synth . SynthEPhs = m_SynthEPhs ;
synth . SynthEFrq = m_SynthEFrq ;
synth . SynthESkew = m_SynthESkew ;
synth . SynthEType = int ( m_SynthEType ) ;
synth . SynthELayer = int ( m_SynthELayer ) ;
synth . SynthF = m_SynthF ;
synth . SynthFPhs = m_SynthFPhs ;
synth . SynthFFrq = m_SynthFFrq ;
synth . SynthFSkew = m_SynthFSkew ;
synth . SynthFType = int ( m_SynthFType ) ;
synth . SynthFLayer = int ( m_SynthFLayer ) ;
synth . SynthMix = m_SynthMix ;
switch ( synthMode )
{
case MODE_SPHERICAL : // Power YES, Smooth YES
// Re-write of spherical with synth tweak
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , ( m_SynthPower + 1 ) / 2 ) ;
// Get angle and angular factor
theta = helper . m_PrecalcAtanxy ;
thetaFactor = SynthValue ( synth , theta ) ;
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_BUBBLE : // Power NO, Smooth YES
// Re-write of bubble with synth tweak
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = helper . m_PrecalcSqrtSumSquares / ( helper . m_PrecalcSumSquares / 4 + 1 ) ;
// Get angle and angular factor
theta = helper . m_PrecalcAtanxy ;
thetaFactor = SynthValue ( synth , theta ) ;
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_BLUR_LEGACY : // Power YES, Smooth YES
// "old" blur style, has some problems with moire-style artefacts
radius = ( rand . Frand01 < T > ( ) + rand . Frand01 < T > ( ) + T ( 0.002 ) * rand . Frand01 < T > ( ) ) / T ( 2.002 ) ;
theta = M_2PI * rand . Frand01 < T > ( ) - T ( M_PI ) ;
Vx = radius * std : : sin ( theta ) ;
Vy = radius * std : : cos ( theta ) ;
radius = std : : pow ( Zeps < T > ( radius * radius ) , m_SynthPower / 2 ) ;
// Get angle and angular factor
thetaFactor = SynthValue ( synth , theta ) ;
radius = m_Weight * Interpolate ( radius , thetaFactor , synthSmooth ) ;
// Write back to running totals for new vector
helper . Out . x = Vx * radius ;
helper . Out . y = Vy * radius ;
break ;
case MODE_BLUR_NEW : // Power YES, Smooth YES
// Blur style, with normal smoothing function
// Choose radius randomly, then adjust distribution using pow
radius = T ( 0.5 ) * ( rand . Frand01 < T > ( ) + rand . Frand01 < T > ( ) ) ;
theta = M_2PI * rand . Frand01 < T > ( ) - T ( M_PI ) ;
radius = std : : pow ( Zeps < T > ( SQR ( radius ) ) , - m_SynthPower / 2 ) ;
// Get angular factor defining the shape
thetaFactor = SynthValue ( synth , theta ) ;
// Get final radius after synth applied
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_BLUR_ZIGZAG : // Power YES, Smooth YES
// Blur effect based on line segment
// theta is used as x value
// Vy is y value
Vy = 1 + T ( 0.1 ) * ( rand . Frand01 < T > ( ) + rand . Frand01 < T > ( ) - 1 ) * m_SynthPower ;
theta = 2 * std : : asin ( ( rand . Frand01 < T > ( ) - T ( 0.5 ) ) * 2 ) ;
// Get angular factor defining the shape
thetaFactor = SynthValue ( synth , theta ) ;
// Get new location
Vy = Interpolate ( Vy , thetaFactor , synthSmooth ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * ( theta / T ( M_PI ) ) ;
helper . Out . y = m_Weight * ( Vy - 1 ) ;
break ;
case MODE_RAWCIRCLE : // Power NO, Smooth YES
// Get current radius and angle
radius = helper . m_PrecalcSqrtSumSquares ;
theta = helper . m_PrecalcAtanxy ;
// Calculate new radius
thetaFactor = SynthValue ( synth , theta ) ;
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_RAWX : // Power NO, Smooth YES
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// x value will be mapped according to synth(y) value
thetaFactor = SynthValue ( synth , Vy ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * Interpolate ( Vx , thetaFactor , synthSmooth ) ;
helper . Out . y = m_Weight * Vy ;
break ;
case MODE_RAWY : // Power NO, Smooth YES
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// y value will be mapped according to synth(x) value
thetaFactor = SynthValue ( synth , Vx ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * Vx ;
helper . Out . y = m_Weight * Interpolate ( Vy , thetaFactor , synthSmooth ) ;
break ;
case MODE_RAWXY : // Power NO, Smooth YES
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// x value will be mapped according to synth(y) value
thetaFactor = SynthValue ( synth , Vy ) ;
helper . Out . x = m_Weight * Interpolate ( Vx , thetaFactor , synthSmooth ) ;
// y value will be mapped according to synth(x) value
thetaFactor = SynthValue ( synth , Vx ) ;
helper . Out . y = m_Weight * Interpolate ( Vy , thetaFactor , synthSmooth ) ;
break ;
case MODE_SHIFTX : // Power NO, Smooth YES
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// Write to running totals for transform
helper . Out . x = m_Weight * ( Vx + SynthValue ( synth , Vy ) - 1 ) ;
helper . Out . y = m_Weight * Vy ;
break ;
case MODE_SHIFTY : // Power NO, Smooth NO
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// Write to running totals for transform
helper . Out . x = m_Weight * Vx ;
helper . Out . y = m_Weight * ( Vy + SynthValue ( synth , Vx ) - 1 ) ;
break ;
case MODE_SHIFTXY : // Power NO, Smooth NO
// Use x and y values directly
Vx = helper . In . x ;
Vy = helper . In . y ;
// Write to running totals for transform
helper . Out . x = m_Weight * ( Vx + SynthValue ( synth , Vy ) - 1 ) ;
helper . Out . y = m_Weight * ( Vy + SynthValue ( synth , Vx ) - 1 ) ;
break ;
case MODE_SINUSOIDAL : // Power NO, Smooth NO
Vx = helper . In . x ;
Vy = helper . In . y ;
// The default mix=0 is same as normal sin
helper . Out . x = m_Weight * ( SynthValue ( synth , Vx ) - 1 + ( 1 - m_SynthMix ) * std : : sin ( Vx ) ) ;
helper . Out . y = m_Weight * ( SynthValue ( synth , Vy ) - 1 + ( 1 - m_SynthMix ) * std : : sin ( Vy ) ) ;
break ;
case MODE_SWIRL : // Power YES, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
// Synth-modified sine & cosine
SynthSinCos ( synth , radius , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * ( s * Vx - c * Vy ) ;
helper . Out . y = m_Weight * ( c * Vx + s * Vy ) ;
break ;
case MODE_HYPERBOLIC : // Power YES, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
theta = helper . m_PrecalcAtanxy ;
// Synth-modified sine & cosine
SynthSinCos ( synth , theta , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * s / radius ;
helper . Out . y = m_Weight * c * radius ;
break ;
case MODE_JULIA : // Power YES, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 4 ) ;
theta = helper . m_PrecalcAtanxy / 2 ;
if ( rand . Frand01 < T > ( ) < T ( 0.5 ) )
theta + = T ( M_PI ) ;
// Synth-modified sine & cosine
SynthSinCos ( synth , theta , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * radius * c ;
helper . Out . y = m_Weight * radius * s ;
break ;
case MODE_DISC : // Power YES, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
theta = helper . m_PrecalcAtanxy / T ( M_PI ) ;
radius = T ( M_PI ) * std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
// Synth-modified sine & cosine
SynthSinCos ( synth , radius , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * s * theta ;
helper . Out . y = m_Weight * c * theta ;
break ;
case MODE_RINGS : // Power PARAM, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = helper . m_PrecalcSqrtSumSquares ;
theta = helper . m_PrecalcAtanxy ;
mu = Zeps < T > ( SQR ( m_SynthPower ) ) ;
radius + = - 2 * mu * int ( ( radius + mu ) / ( 2 * mu ) ) + radius * ( 1 - mu ) ;
SynthSinCos ( synth , radius , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * s * theta ;
helper . Out . y = m_Weight * c * theta ;
break ;
case MODE_CYLINDER : // Power YES, Smooth WAVE
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
// Modified sine only used here
SynthSinCos ( synth , Vx , s , c , synthSmooth ) ;
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * Vy ;
break ;
case MODE_BLUR_RING : // Power YES, Smooth YES
// Blur style, with normal smoothing function
radius = 1 + T ( 0.1 ) * ( rand . Frand01 < T > ( ) + rand . Frand01 < T > ( ) - 1 ) * m_SynthPower ;
theta = M_2PI * rand . Frand01 < T > ( ) - T ( M_PI ) ;
// Get angular factor defining the shape
thetaFactor = SynthValue ( synth , theta ) ;
// Get final radius after synth applied
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_BLUR_RING2 : // Power YES, Smooth NO
// Simple, same-thickness ring
// Choose radius randomly, then adjust distribution using pow
theta = M_2PI * rand . Frand01 < T > ( ) - T ( M_PI ) ;
radius = std : : pow ( Zeps < T > ( rand . Frand01 < T > ( ) ) , m_SynthPower ) ;
// Get final radius after synth applied
radius = SynthValue ( synth , theta ) + T ( 0.1 ) * radius ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_SHIFTTHETA : // Power YES, Smooth NO
// Use (adjusted) radius to move point around circle
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
theta = helper . m_PrecalcAtanxy - 1 + SynthValue ( synth , radius ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_SHIFTNSTRETCH :
// Use (adjusted) radius to move point around circle
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
theta = helper . m_PrecalcAtanxy - 1 + SynthValue ( synth , radius ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
case MODE_SHIFTTANGENT :
// Use (adjusted) radius to move point tangentially to circle
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = std : : pow ( Zeps < T > ( helper . m_PrecalcSumSquares ) , m_SynthPower / 2 ) ;
sincos ( helper . m_PrecalcAtanxy , & s , & c ) ;
// Adjust Vx and Vy directly
mu = SynthValue ( synth , radius ) - 1 ;
Vx + = mu * c ;
Vy - = mu * s ;
// Write to running totals for transform
helper . Out . x = m_Weight * Vx ;
helper . Out . y = m_Weight * Vy ;
break ;
case MODE_XMIRROR :
Vx = helper . In . x ;
Vy = helper . In . y ;
// Modified sine only used here
mu = SynthValue ( synth , Vx ) - 1 ;
Vy = 2 * mu - Vy ;
helper . Out . x = m_Weight * Vx ;
helper . Out . y = m_Weight * Vy ;
break ;
case MODE_XYMIRROR :
Vx = helper . In . x ;
Vy = helper . In . y ;
// radius sneakily being used to represent something completely different, sorry!
mu = SynthValue ( synth , Vx ) - 1 ;
radius = SynthValue ( synth , Vy ) - 1 ;
Vy = 2 * mu - Vy ;
Vx = 2 * radius - Vx ;
helper . Out . x = m_Weight * Vx ;
helper . Out . y = m_Weight * Vy ;
break ;
case MODE_SPHERICAL2 :
default :
Vx = helper . In . x ;
Vy = helper . In . y ;
radius = helper . m_PrecalcSqrtSumSquares ;
// Get angle and angular factor
theta = helper . m_PrecalcAtanxy ;
thetaFactor = SynthValue ( synth , theta ) ;
radius = Interpolate ( radius , thetaFactor , synthSmooth ) ;
radius = std : : pow ( radius , m_SynthPower ) ;
sincos ( theta , & s , & c ) ;
// Write to running totals for transform
helper . Out . x = m_Weight * radius * s ;
helper . Out . y = m_Weight * radius * c ;
break ;
}
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string synthA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthMode = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthPower = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthMix = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthSmooth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthB = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthBType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthBSkew = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthBFrq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthBPhs = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthBLayer = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthC = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthCType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthCSkew = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthCFrq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthCPhs = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthCLayer = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthD = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthDType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthDSkew = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthDFrq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthDPhs = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthDLayer = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthE = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthEType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthESkew = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthEFrq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthEPhs = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthELayer = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthF = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthFType = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthFSkew = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthFFrq = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthFPhs = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string synthFLayer = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t Vx, Vy, radius, theta; \n "
< < " \t \t real_t thetaFactor; \n "
< < " \t \t real_t s, c, mu; \n "
< < " \t \t int synthMode = (int) " < < synthMode < < " ; \n "
< < " \t \t int synthSmooth = (int) " < < synthSmooth < < " ; \n "
< < " \t \t SynthStruct synth; \n "
< < " \n "
< < " \t \t synth.SynthA = " < < synthA < < " ; \n "
< < " \t \t synth.SynthB = " < < synthB < < " ; \n "
< < " \t \t synth.SynthBPhs = " < < synthBPhs < < " ; \n "
< < " \t \t synth.SynthBFrq = " < < synthBFrq < < " ; \n "
< < " \t \t synth.SynthBSkew = " < < synthBSkew < < " ; \n "
< < " \t \t synth.SynthBType = (int) " < < synthBType < < " ; \n "
< < " \t \t synth.SynthBLayer = (int) " < < synthBLayer < < " ; \n "
< < " \t \t synth.SynthC = " < < synthC < < " ; \n "
< < " \t \t synth.SynthCPhs = " < < synthCPhs < < " ; \n "
< < " \t \t synth.SynthCFrq = " < < synthCFrq < < " ; \n "
< < " \t \t synth.SynthCSkew = " < < synthCSkew < < " ; \n "
< < " \t \t synth.SynthCType = (int) " < < synthCType < < " ; \n "
< < " \t \t synth.SynthCLayer = (int) " < < synthCLayer < < " ; \n "
< < " \t \t synth.SynthD = " < < synthD < < " ; \n "
< < " \t \t synth.SynthDPhs = " < < synthDPhs < < " ; \n "
< < " \t \t synth.SynthDFrq = " < < synthDFrq < < " ; \n "
< < " \t \t synth.SynthDSkew = " < < synthDSkew < < " ; \n "
< < " \t \t synth.SynthDType = (int) " < < synthDType < < " ; \n "
< < " \t \t synth.SynthDLayer = (int) " < < synthDLayer < < " ; \n "
< < " \t \t synth.SynthE = " < < synthE < < " ; \n "
< < " \t \t synth.SynthEPhs = " < < synthEPhs < < " ; \n "
< < " \t \t synth.SynthEFrq = " < < synthEFrq < < " ; \n "
< < " \t \t synth.SynthESkew = " < < synthESkew < < " ; \n "
< < " \t \t synth.SynthEType = (int) " < < synthEType < < " ; \n "
< < " \t \t synth.SynthELayer = (int) " < < synthELayer < < " ; \n "
< < " \t \t synth.SynthF = " < < synthF < < " ; \n "
< < " \t \t synth.SynthFPhs = " < < synthFPhs < < " ; \n "
< < " \t \t synth.SynthFFrq = " < < synthFFrq < < " ; \n "
< < " \t \t synth.SynthFSkew = " < < synthFSkew < < " ; \n "
< < " \t \t synth.SynthFType = (int) " < < synthFType < < " ; \n "
< < " \t \t synth.SynthFLayer = (int) " < < synthFLayer < < " ; \n "
< < " \t \t synth.SynthMix = " < < synthMix < < " ; \n "
< < " \n "
< < " \t \t switch (synthMode) \n "
< < " \t \t { \n "
< < " \t \t case MODE_SPHERICAL: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), ( " < < synthPower < < " + 1) / 2); \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BUBBLE: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = precalcSqrtSumSquares / (precalcSumSquares / 4 + 1); \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BLUR_LEGACY: \n "
< < " \t \t radius = fma((real_t)(0.002), MwcNext01(mwc), MwcNext01(mwc) + MwcNext01(mwc)) / 2.002; \n "
< < " \t \t theta = fma(M_2PI, MwcNext01(mwc), -MPI); \n "
< < " \t \t Vx = radius * sin(theta); \n "
< < " \t \t Vy = radius * cos(theta); \n "
< < " \t \t radius = pow(Zeps(radius * radius), " < < synthPower < < " / 2); \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = " < < weight < < " * Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t vOut.x = Vx * radius; \n "
< < " \t \t vOut.y = Vy * radius; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BLUR_NEW: \n "
< < " \t \t radius = 0.5 * (MwcNext01(mwc) + MwcNext01(mwc)); \n "
< < " \t \t theta = fma(M_2PI, MwcNext01(mwc), -MPI); \n "
< < " \t \t radius = pow(Zeps(SQR(radius)), - " < < synthPower < < " / 2); \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BLUR_ZIGZAG: \n "
< < " \t \t Vy = fma((real_t)(0.1), (MwcNext01(mwc) + MwcNext01(mwc) - 1) * " < < synthPower < < " , (real_t)(1.0)); \n "
< < " \t \t theta = 2 * asin((MwcNext01(mwc) - 0.5) * 2); \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t Vy = Interpolate(Vy, thetaFactor, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * (theta / MPI); \n "
< < " \t \t vOut.y = " < < weight < < " * (Vy - 1); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_RAWCIRCLE: \n "
< < " \t \t radius = precalcSqrtSumSquares; \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_RAWX: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t thetaFactor = SynthValue(&synth, Vy); \n "
< < " \t \t vOut.x = " < < weight < < " * Interpolate(Vx, thetaFactor, synthSmooth); \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_RAWY: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t thetaFactor = SynthValue(&synth, Vx); \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * Interpolate(Vy, thetaFactor, synthSmooth); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_RAWXY: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t thetaFactor = SynthValue(&synth, Vy); \n "
< < " \t \t vOut.x = " < < weight < < " * Interpolate(Vx, thetaFactor, synthSmooth); \n "
< < " \t \t thetaFactor = SynthValue(&synth, Vx); \n "
< < " \t \t vOut.y = " < < weight < < " * Interpolate(Vy, thetaFactor, synthSmooth); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SHIFTX: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t vOut.x = " < < weight < < " * (Vx + SynthValue(&synth, Vy) - 1); \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SHIFTY: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * (Vy + SynthValue(&synth, Vx) - 1); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SHIFTXY: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t vOut.x = " < < weight < < " * (Vx + SynthValue(&synth, Vy) - 1); \n "
< < " \t \t vOut.y = " < < weight < < " * (Vy + SynthValue(&synth, Vx) - 1); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SINUSOIDAL: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t vOut.x = " < < weight < < " * fma((real_t)(1.0) - " < < synthMix < < " , sin(Vx), SynthValue(&synth, Vx) - (real_t)(1.0)); \n "
< < " \t \t vOut.y = " < < weight < < " * fma((real_t)(1.0) - " < < synthMix < < " , sin(Vy), SynthValue(&synth, Vy) - (real_t)(1.0)); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SWIRL: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t SynthSinCos(&synth, radius, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * fma(s, Vx, -(c * Vy)); \n "
< < " \t \t vOut.y = " < < weight < < " * fma(c, Vx, s * Vy); \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_HYPERBOLIC: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t SynthSinCos(&synth, theta, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * s / radius; \n "
< < " \t \t vOut.y = " < < weight < < " * c * radius; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_JULIA: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 4); \n "
< < " \t \t theta = precalcAtanxy / 2; \n "
< < " \n "
< < " \t \t if (MwcNext01(mwc) < 0.5) \n "
< < " \t \t theta += MPI; \n "
< < " \n "
< < " \t \t SynthSinCos(&synth, theta, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * c; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * s; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_DISC: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t theta = precalcAtanxy / MPI; \n "
< < " \t \t radius = MPI * pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t SynthSinCos(&synth, radius, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * s * theta; \n "
< < " \t \t vOut.y = " < < weight < < " * c * theta; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_RINGS: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = precalcSqrtSumSquares; \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t mu = Zeps(SQR( " < < synthPower < < " )); \n "
< < " \t \t radius += fma((real_t)(-2.0) * mu, (real_t)(int)((radius + mu) / (2 * mu)), radius * ((real_t)(1.0) - mu)); \n "
< < " \t \t SynthSinCos(&synth, radius, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * s * theta; \n "
< < " \t \t vOut.y = " < < weight < < " * c * theta; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_CYLINDER: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t SynthSinCos(&synth, Vx, &s, &c, synthSmooth); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BLUR_RING: \n "
< < " \t \t radius = fma((real_t)(0.1) * " < < synthPower < < " , MwcNext01(mwc) + MwcNext01(mwc) - (real_t)(1.0), (real_t)(1.0)); \n "
< < " \t \t theta = M_2PI * MwcNext01(mwc) - MPI; \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_BLUR_RING2: \n "
< < " \t \t theta = fma(M_2PI, MwcNext01(mwc), -MPI); \n "
< < " \t \t radius = pow(Zeps(MwcNext01(mwc)), " < < synthPower < < " ); \n "
< < " \t \t radius = fma((real_t)(0.1), radius, SynthValue(&synth, theta)); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SHIFTTHETA: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t theta = precalcAtanxy - 1 + SynthValue(&synth, radius); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \t \t case MODE_SHIFTNSTRETCH: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t theta = precalcAtanxy - 1 + SynthValue(&synth, radius); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SHIFTTANGENT: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = pow(Zeps(precalcSumSquares), " < < synthPower < < " / 2); \n "
< < " \t \t s = sincos(precalcAtanxy, &c); \n "
< < " \t \t mu = SynthValue(&synth, radius) - 1; \n "
< < " \t \t Vx += mu * c; \n "
< < " \t \t Vy -= mu * s; \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_XMIRROR: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t mu = SynthValue(&synth, Vx) - 1; \n "
< < " \t \t Vy = fma((real_t)(2.0), mu, -Vy); \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_XYMIRROR: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t mu = SynthValue(&synth, Vx) - 1; \n "
< < " \t \t radius = SynthValue(&synth, Vy) - 1; \n "
< < " \t \t Vy = fma((real_t)(2.0), mu, -Vy); \n "
< < " \t \t Vx = fma((real_t)(2.0), radius, -Vx); \n "
< < " \t \t vOut.x = " < < weight < < " * Vx; \n "
< < " \t \t vOut.y = " < < weight < < " * Vy; \n "
< < " \t \t break; \n "
< < " \n "
< < " \t \t case MODE_SPHERICAL2: \n "
< < " \t \t default: \n "
< < " \t \t Vx = vIn.x; \n "
< < " \t \t Vy = vIn.y; \n "
< < " \t \t radius = precalcSqrtSumSquares; \n "
< < " \t \t theta = precalcAtanxy; \n "
< < " \t \t thetaFactor = SynthValue(&synth, theta); \n "
< < " \t \t radius = Interpolate(radius, thetaFactor, synthSmooth); \n "
< < " \t \t radius = pow(radius, " < < synthPower < < " ); \n "
< < " \t \t s = sincos(theta, &c); \n "
< < " \t \t vOut.x = " < < weight < < " * radius * s; \n "
< < " \t \t vOut.y = " < < weight < < " * radius * c; \n "
< < " \t \t break; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " , " Sqr " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
return
" #define MODE_SPHERICAL 0 \n "
" #define MODE_BUBBLE 1 \n "
" #define MODE_BLUR_LEGACY 2 \n "
" #define MODE_BLUR_NEW 3 \n "
" #define MODE_BLUR_ZIGZAG 4 \n "
" #define MODE_RAWCIRCLE 5 \n "
" #define MODE_RAWX 6 \n "
" #define MODE_RAWY 7 \n "
" #define MODE_RAWXY 8 \n "
" #define MODE_SHIFTX 9 \n "
" #define MODE_SHIFTY 10 \n "
" #define MODE_SHIFTXY 11 \n "
" #define MODE_SINUSOIDAL 12 \n "
" #define MODE_SWIRL 13 \n "
" #define MODE_HYPERBOLIC 14 \n "
" #define MODE_JULIA 15 \n "
" #define MODE_DISC 16 \n "
" #define MODE_RINGS 17 \n "
" #define MODE_CYLINDER 18 \n "
" #define MODE_BLUR_RING 19 \n "
" #define MODE_BLUR_RING2 20 \n "
" #define MODE_SHIFTTHETA 21 \n "
" #define MODE_SHIFTNSTRETCH 22 \n "
" #define MODE_SHIFTTANGENT 23 \n "
" #define MODE_XMIRROR 24 \n "
" #define MODE_XYMIRROR 25 \n "
" #define MODE_SPHERICAL2 26 \n "
" #define WAVE_SIN 0 \n "
" #define WAVE_COS 1 \n "
" #define WAVE_SQUARE 2 \n "
" #define WAVE_SAW 3 \n "
" #define WAVE_TRIANGLE 4 \n "
" #define WAVE_CONCAVE 5 \n "
" #define WAVE_CONVEX 6 \n "
" #define WAVE_NGON 7 \n "
" #define WAVE_INGON 8 \n "
" #define LAYER_ADD 0 \n "
" #define LAYER_MULT 1 \n "
" #define LAYER_MAX 2 \n "
" #define LAYER_MIN 3 \n "
" #define LERP_LINEAR 0 \n "
" #define LERP_BEZIER 1 \n "
" #define SINCOS_MULTIPLY 0 \n "
" #define SINCOS_MIXIN 1 \n "
" \n "
" typedef struct __attribute__ " ALIGN_CL " _SynthStruct \n "
" { \n "
" real_t SynthA; \n "
" real_t SynthB; \n "
" real_t SynthBPhs; \n "
" real_t SynthBFrq; \n "
" real_t SynthBSkew; \n "
" int SynthBType; \n "
" int SynthBLayer; \n "
" real_t SynthC; \n "
" real_t SynthCPhs; \n "
" real_t SynthCFrq; \n "
" real_t SynthCSkew; \n "
" int SynthCType; \n "
" int SynthCLayer; \n "
" real_t SynthD; \n "
" real_t SynthDPhs; \n "
" real_t SynthDFrq; \n "
" real_t SynthDSkew; \n "
" int SynthDType; \n "
" int SynthDLayer; \n "
" real_t SynthE; \n "
" real_t SynthEPhs; \n "
" real_t SynthEFrq; \n "
" real_t SynthESkew; \n "
" int SynthEType; \n "
" int SynthELayer; \n "
" real_t SynthF; \n "
" real_t SynthFPhs; \n "
" real_t SynthFFrq; \n "
" real_t SynthFSkew; \n "
" int SynthFType; \n "
" int SynthFLayer; \n "
" real_t SynthMix; \n "
" } SynthStruct; \n "
" \n "
" static void SynthValueProc(real_t* synthA, real_t* thetaFactor, real_t theta, real_t* synth, real_t* phs, real_t* frq, real_t* skew, real_t* x, real_t* y, real_t* z, int* type, int* layer) \n "
" { \n "
" if (*synth != 0) \n "
" { \n "
" *z = fma(theta, *frq, *phs); \n "
" *y = *z / M_2PI; \n "
" *y -= floor(*y); \n "
" \n "
" if (*skew != 0) \n "
" { \n "
" *z = fma((real_t)(0.5), *skew, (real_t)(0.5)); \n "
" \n "
" if (*y > *z) \n "
" *y = fma((real_t)(0.5), (*y - *z) / Zeps(1 - *z), (real_t)(0.5)); \n "
" else \n "
" *y = 0.5 - 0.5 * (*z - *y) / Zeps(*z); \n "
" } \n "
" \n "
" switch (*type) \n "
" { \n "
" case WAVE_SIN: \n "
" *x = sin(*y * M_2PI); \n "
" break; \n "
" case WAVE_COS: \n "
" *x = cos(*y * M_2PI); \n "
" break; \n "
" case WAVE_SQUARE: \n "
" *x = *y > 0.5 ? 1.0 : -1.0; \n "
" break; \n "
" case WAVE_SAW: \n "
" *x = 1 - 2 * *y; \n "
" break; \n "
" case WAVE_TRIANGLE: \n "
" *x = *y > 0.5 ? 3 - 4 * *y : fma((real_t)(2.0), *y, (real_t)(-1.0)); \n "
" break; \n "
" case WAVE_CONCAVE: \n "
" *x = fma((real_t)(8.0), Sqr(*y - 0.5), (real_t)(-1.0)); \n "
" break; \n "
" case WAVE_CONVEX: \n "
" *x = fma((real_t)(2.0), sqrt(*y), (real_t)(-1.0)); \n "
" break; \n "
" case WAVE_NGON: \n "
" *y -= 0.5; \n "
" *y *= M_2PI / *frq; \n "
" *x = 1 / Zeps(cos(*y)) - 1; \n "
" break; \n "
" case WAVE_INGON: \n "
" *y -= 0.5; \n "
" *y *= M_2PI / *frq; \n "
" *z = cos(*y); \n "
" *x = *z / Zeps(1 - *z); \n "
" break; \n "
" } \n "
" \n "
" switch (*layer) \n "
" { \n "
" case LAYER_ADD: \n "
" *thetaFactor += *synth * *x; \n "
" break; \n "
" case LAYER_MULT: \n "
" *thetaFactor *= fma(*synth, *x, (real_t)(1.0)); \n "
" break; \n "
" case LAYER_MAX: \n "
" *z = fma(*synth, *x, *synthA); \n "
" *thetaFactor = (*thetaFactor > *z ? *thetaFactor : *z); \n "
" break; \n "
" case LAYER_MIN: \n "
" *z = fma(*synth, *x, *synthA); \n "
" *thetaFactor = (*thetaFactor < *z ? *thetaFactor : *z); \n "
" break; \n "
" } \n "
" } \n "
" } \n "
" \n "
" static real_t SynthValue(SynthStruct* s, real_t theta) \n "
" { \n "
" real_t x, y, z; \n "
" real_t thetaFactor = s->SynthA; \n "
" \n "
" SynthValueProc(&(s->SynthA), &thetaFactor, theta, &(s->SynthB), &(s->SynthBPhs), &(s->SynthBFrq), &(s->SynthBSkew), &x, &y, &z, &(s->SynthBType), &(s->SynthBLayer)); \n "
" SynthValueProc(&(s->SynthA), &thetaFactor, theta, &(s->SynthC), &(s->SynthCPhs), &(s->SynthCFrq), &(s->SynthCSkew), &x, &y, &z, &(s->SynthCType), &(s->SynthCLayer)); \n "
" SynthValueProc(&(s->SynthA), &thetaFactor, theta, &(s->SynthD), &(s->SynthDPhs), &(s->SynthDFrq), &(s->SynthDSkew), &x, &y, &z, &(s->SynthDType), &(s->SynthDLayer)); \n "
" SynthValueProc(&(s->SynthA), &thetaFactor, theta, &(s->SynthE), &(s->SynthEPhs), &(s->SynthEFrq), &(s->SynthESkew), &x, &y, &z, &(s->SynthEType), &(s->SynthELayer)); \n "
" SynthValueProc(&(s->SynthA), &thetaFactor, theta, &(s->SynthF), &(s->SynthFPhs), &(s->SynthFFrq), &(s->SynthFSkew), &x, &y, &z, &(s->SynthFType), &(s->SynthFLayer)); \n "
" \n "
" return fma(thetaFactor, s->SynthMix, (1 - s->SynthMix)); \n "
" } \n "
" \n "
" static real_t BezierQuadMap(real_t x, real_t m) \n "
" { \n "
" real_t a = 1; \n "
" real_t t = 0; \n "
" \n "
" if (m < 0) { m = -m; a = -1; } \n "
" if (x < 0) { x = -x; a = -a; } \n "
" \n "
" real_t iM = 1e10; \n "
" \n "
" if (m > 1.0e-10) \n "
" iM = 1 / m; \n "
" \n "
" real_t L = iM < m * 2 ? m * 2 : iM; \n "
" \n "
" if ((x > L) || (m == 1)) \n "
" return a * x; \n "
" \n "
" if ((m < 1) && (x <= 1)) \n "
" { \n "
" t = x; \n "
" \n "
" if (fabs(m - 0.5) > 1e-10) \n "
" t = fma((real_t)(-1.0), m, sqrt(fma(m, m, ((real_t)(1.0) - (real_t)(2.0) * m) * x))) / ((real_t)(1.0) - (real_t)(2.0) * m); \n "
" \n "
" return a * fma(m - (real_t)(1.0), SQR(t), x); \n "
" } \n "
" \n "
" if ((1 < m) && (x <= 1)) \n "
" { \n "
" t = x; \n "
" \n "
" if (fabs(m - 2) > 1e-10) \n "
" t = fma((real_t)(-1.0), iM, sqrt(fma(iM, iM, ((real_t)(1.0) - (real_t)(2.0) * iM) * x))) / ((real_t)(1.0) - (real_t)(2.0) * iM); \n "
" \n "
" return a * fma(m - (real_t)(1.0), SQR(t), x); \n "
" } \n "
" \n "
" if (m < 1) \n "
" { \n "
" t = sqrt((x - 1) / (L - 1)); \n "
" return a * fma((m - 1), t * t, x + fma((real_t)(2.0), ((real_t)(1.0) - m) * t, (m - 1))); \n "
" } \n "
" \n "
" t = (1 - m) + sqrt(fma((m - (real_t)(1.0)), (m - (real_t)(1.0)), (x - (real_t)(1.0)))); \n "
" return a * fma((m - (real_t)(1.0)), t * t, x - fma((real_t)(2.0), (m - (real_t)(1.0)) * t, (m - (real_t)(1.0)))); \n "
" } \n "
" \n "
" static real_t Interpolate(real_t x, real_t m, int lerpType) \n "
" { \n "
" switch (lerpType) \n "
" { \n "
" case LERP_LINEAR: \n "
" return x * m; \n "
" case LERP_BEZIER: \n "
" return BezierQuadMap(x, m); \n "
" } \n "
" \n "
" return x * m; \n "
" } \n "
" \n "
" static void SynthSinCos(SynthStruct* synth, real_t theta, real_t* s, real_t* c, int sineType) \n "
" { \n "
" *s = sincos(theta, c); \n "
" \n "
" switch (sineType) \n "
" { \n "
" case SINCOS_MULTIPLY: \n "
" *s = *s * SynthValue(synth, theta); \n "
" *c = *c * SynthValue(synth, theta + MPI / (real_t)(2.0)); \n "
" break; \n "
" case SINCOS_MIXIN: \n "
" *s = fma(((real_t)(1.0) - synth->SynthMix), *s, (SynthValue(synth, theta) - (real_t)(1.0))); \n "
" *c = fma(((real_t)(1.0) - synth->SynthMix), *c, (SynthValue(synth, theta + MPI / (real_t)(2.0)) - (real_t)(1.0))); \n "
" break; \n "
" } \n "
" \n "
" return; \n "
" } \n \n "
;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 34 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthA , prefix + " synth_a " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthMode , prefix + " synth_mode " , 3 , eParamType : : INTEGER , MODE_SPHERICAL , MODE_SPHERICAL2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthPower , prefix + " synth_power " , - 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthMix , prefix + " synth_mix " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthSmooth , prefix + " synth_smooth " , 0 , eParamType : : INTEGER , LERP_LINEAR , LERP_BEZIER ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthB , prefix + " synth_b " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthBType , prefix + " synth_b_type " , 0 , eParamType : : INTEGER , WAVE_SIN , WAVE_INGON ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthBSkew , prefix + " synth_b_skew " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthBFrq , prefix + " synth_b_frq " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthBPhs , prefix + " synth_b_phs " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthBLayer , prefix + " synth_b_layer " , 0 , eParamType : : INTEGER , LAYER_ADD , LAYER_MIN ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthC , prefix + " synth_c " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthCType , prefix + " synth_c_type " , 0 , eParamType : : INTEGER , WAVE_SIN , WAVE_INGON ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthCSkew , prefix + " synth_c_skew " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthCFrq , prefix + " synth_c_frq " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthCPhs , prefix + " synth_c_phs " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthCLayer , prefix + " synth_c_layer " , 0 , eParamType : : INTEGER , LAYER_ADD , LAYER_MIN ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthD , prefix + " synth_d " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthDType , prefix + " synth_d_type " , 0 , eParamType : : INTEGER , WAVE_SIN , WAVE_INGON ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthDSkew , prefix + " synth_d_skew " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthDFrq , prefix + " synth_d_frq " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthDPhs , prefix + " synth_d_phs " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthDLayer , prefix + " synth_d_layer " , 0 , eParamType : : INTEGER , LAYER_ADD , LAYER_MIN ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthE , prefix + " synth_e " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthEType , prefix + " synth_e_type " , 0 , eParamType : : INTEGER , WAVE_SIN , WAVE_INGON ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthESkew , prefix + " synth_e_skew " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthEFrq , prefix + " synth_e_frq " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthEPhs , prefix + " synth_e_phs " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthELayer , prefix + " synth_e_layer " , 0 , eParamType : : INTEGER , LAYER_ADD , LAYER_MIN ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthF , prefix + " synth_f " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthFType , prefix + " synth_f_type " , 0 , eParamType : : INTEGER , WAVE_SIN , WAVE_INGON ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthFSkew , prefix + " synth_f_skew " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthFFrq , prefix + " synth_f_frq " , 1 , eParamType : : REAL ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthFPhs , prefix + " synth_f_phs " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SynthFLayer , prefix + " synth_f_layer " , 0 , eParamType : : INTEGER , LAYER_ADD , LAYER_MIN ) ) ;
}
private :
struct SynthStruct
{
T SynthA ;
T SynthB ;
T SynthBPhs ;
T SynthBFrq ;
T SynthBSkew ;
int SynthBType ;
int SynthBLayer ;
T SynthC ;
T SynthCPhs ;
T SynthCFrq ;
T SynthCSkew ;
int SynthCType ;
int SynthCLayer ;
T SynthD ;
T SynthDPhs ;
T SynthDFrq ;
T SynthDSkew ;
int SynthDType ;
int SynthDLayer ;
T SynthE ;
T SynthEPhs ;
T SynthEFrq ;
T SynthESkew ;
int SynthEType ;
int SynthELayer ;
T SynthF ;
T SynthFPhs ;
T SynthFFrq ;
T SynthFSkew ;
int SynthFType ;
int SynthFLayer ;
T SynthMix ;
} ;
inline void SynthValueProc ( T & synthA , T & thetaFactor , T theta , T & synth , T & phs , T & frq , T & skew , T & x , T & y , T & z , int & type , int & layer )
{
if ( synth ! = 0 )
{
z = phs + theta * frq ;
y = z / M_2PI ;
y - = Floor < T > ( y ) ;
// y is in range 0 - 1. Now skew according to synth_f_skew
if ( skew ! = 0 )
{
z = T ( 0.5 ) + T ( 0.5 ) * skew ;
if ( y > z )
y = T ( 0.5 ) + T ( 0.5 ) * ( y - z ) / Zeps < T > ( 1 - z ) ; // y is T(0.5) if equals z, up to 1.0
else
y = T ( 0.5 ) - T ( 0.5 ) * ( z - y ) / Zeps < T > ( z ) ; // y is T(0.5) if equals z, down to 0.0
}
switch ( type )
{
case WAVE_SIN :
x = std : : sin ( y * M_2PI ) ;
break ;
case WAVE_COS :
x = std : : cos ( y * M_2PI ) ;
break ;
case WAVE_SQUARE :
x = y > T ( 0.5 ) ? T ( 1 ) : T ( - 1 ) ;
break ;
case WAVE_SAW :
x = 1 - 2 * y ;
break ;
case WAVE_TRIANGLE :
x = y > T ( 0.5 ) ? 3 - 4 * y : 2 * y - 1 ;
break ;
case WAVE_CONCAVE :
x = 8 * ( y - T ( 0.5 ) ) * ( y - T ( 0.5 ) ) - 1 ;
break ;
case WAVE_CONVEX :
x = 2 * std : : sqrt ( y ) - 1 ;
break ;
case WAVE_NGON :
y - = T ( 0.5 ) ;
y * = M_2PI / frq ;
x = 1 / Zeps < T > ( std : : cos ( y ) ) - 1 ;
break ;
default :
case WAVE_INGON :
y - = T ( 0.5 ) ;
y * = M_2PI / frq ;
z = std : : cos ( y ) ;
x = z / Zeps < T > ( 1 - z ) ;
break ;
}
switch ( layer )
{
case LAYER_ADD :
thetaFactor + = synth * x ;
break ;
case LAYER_MULT :
thetaFactor * = ( 1 + synth * x ) ;
break ;
case LAYER_MAX :
z = synthA + synth * x ;
thetaFactor = ( thetaFactor > z ? thetaFactor : z ) ;
break ;
default :
case LAYER_MIN :
z = synthA + synth * x ;
thetaFactor = ( thetaFactor < z ? thetaFactor : z ) ;
break ;
}
}
}
inline T SynthValue ( SynthStruct & s , T theta )
{
T x , y , z ;
T thetaFactor = s . SynthA ;
SynthValueProc ( s . SynthA , thetaFactor , theta , s . SynthB , s . SynthBPhs , s . SynthBFrq , s . SynthBSkew , x , y , z , s . SynthBType , s . SynthBLayer ) ;
SynthValueProc ( s . SynthA , thetaFactor , theta , s . SynthC , s . SynthCPhs , s . SynthCFrq , s . SynthCSkew , x , y , z , s . SynthCType , s . SynthCLayer ) ;
SynthValueProc ( s . SynthA , thetaFactor , theta , s . SynthD , s . SynthDPhs , s . SynthDFrq , s . SynthDSkew , x , y , z , s . SynthDType , s . SynthDLayer ) ;
SynthValueProc ( s . SynthA , thetaFactor , theta , s . SynthE , s . SynthEPhs , s . SynthEFrq , s . SynthESkew , x , y , z , s . SynthEType , s . SynthELayer ) ;
SynthValueProc ( s . SynthA , thetaFactor , theta , s . SynthF , s . SynthFPhs , s . SynthFFrq , s . SynthFSkew , x , y , z , s . SynthFType , s . SynthFLayer ) ;
// Mix is applied here, assuming 1.0 to be the "flat" line for legacy support
return thetaFactor * s . SynthMix + ( 1 - s . SynthMix ) ;
}
inline T BezierQuadMap ( T x , T m )
{
T a = 1 ; // a is used to control sign of result
T t = 0 ; // t is the Bezier curve parameter
// Simply reflect in the y axis for negative values
if ( m < 0 ) { m = - m ; a = - 1 ; }
if ( x < 0 ) { x = - x ; a = - a ; }
// iM is "inverse m" used in a few places below
T iM = T ( 1e10 ) ;
if ( m > 1.0e-10 )
iM = 1 / m ;
// L is the upper bound on our curves, where we have rejoined the y = x line
T L = iM < m * 2 ? m * 2 : iM ;
// "Non Curved"
// Covers x >= L, or always true if m == 1.0
// y = x i.e. not distorted
if ( ( x > L ) | | ( m = = 1 ) )
return a * x ;
if ( ( m < 1 ) & & ( x < = 1 ) )
{
// Bezier Curve #1
// Covers 0 <= $m <= 1.0, 0 <= $x <= 1.0
// Control points are (0,0), (m,m) and (1,m)
t = x ; // Special case when m == 0.5
if ( std : : abs ( m - T ( 0.5 ) ) > 1e-10 )
t = ( - 1 * m + std : : sqrt ( m * m + ( 1 - 2 * m ) * x ) ) / ( 1 - 2 * m ) ;
return a * ( x + ( m - 1 ) * t * t ) ;
}
if ( ( 1 < m ) & & ( x < = 1 ) )
{
// Bezier Curve #2
// Covers m >= 1.0, 0 <= x <= 1.0
// Control points are (0,0), (iM,iM) and (1,m)
t = x ; // Special case when m == 2
if ( std : : abs ( m - 2 ) > 1e-10 )
t = ( - 1 * iM + std : : sqrt ( iM * iM + ( 1 - 2 * iM ) * x ) ) / ( 1 - 2 * iM ) ;
return a * ( x + ( m - 1 ) * t * t ) ;
}
if ( m < 1 )
{
// Bezier Curve #3
// Covers 0 <= m <= 1.0, 1 <= x <= L
// Control points are (1,m), (1,1) and (L,L)
// (L is x value (>1) where we re-join y = x line, and is maximum( iM, 2 * m )
t = std : : sqrt ( ( x - 1 ) / ( L - 1 ) ) ;
return a * ( x + ( m - 1 ) * t * t + 2 * ( 1 - m ) * t + ( m - 1 ) ) ;
}
// Curve #4
// Covers 1.0 <= m, 1 <= x <= L
// Control points are (1,m), (m,m) and (L,L)
// (L is x value (>1) where we re-join y = x line, and is maximum( iM, 2 * m )
t = ( 1 - m ) + std : : sqrt ( ( m - 1 ) * ( m - 1 ) + ( x - 1 ) ) ;
return a * ( x + ( m - 1 ) * t * t - 2 * ( m - 1 ) * t + ( m - 1 ) ) ;
}
inline T Interpolate ( T x , T m , int lerpType )
{
switch ( lerpType )
{
case LERP_LINEAR :
return x * m ;
default :
case LERP_BEZIER :
return BezierQuadMap ( x , m ) ;
}
}
inline void SynthSinCos ( SynthStruct & synth , T theta , T & s , T & c , int sineType )
{
sincos ( theta , & s , & c ) ;
switch ( sineType )
{
case SINCOS_MULTIPLY :
s = s * SynthValue ( synth , theta ) ;
c = c * SynthValue ( synth , theta + T ( M_PI ) / 2 ) ;
break ;
default :
case SINCOS_MIXIN :
s = ( 1 - m_SynthMix ) * s + ( SynthValue ( synth , theta ) - 1 ) ;
c = ( 1 - m_SynthMix ) * c + ( SynthValue ( synth , theta + T ( M_PI ) / 2 ) - 1 ) ;
break ;
}
return ;
}
T m_SynthA ;
T m_SynthMode ;
T m_SynthPower ;
T m_SynthMix ;
T m_SynthSmooth ;
T m_SynthB ;
T m_SynthBType ;
T m_SynthBSkew ;
T m_SynthBFrq ;
T m_SynthBPhs ;
T m_SynthBLayer ;
T m_SynthC ;
T m_SynthCType ;
T m_SynthCSkew ;
T m_SynthCFrq ;
T m_SynthCPhs ;
T m_SynthCLayer ;
T m_SynthD ;
T m_SynthDType ;
T m_SynthDSkew ;
T m_SynthDFrq ;
T m_SynthDPhs ;
T m_SynthDLayer ;
T m_SynthE ;
T m_SynthEType ;
T m_SynthESkew ;
T m_SynthEFrq ;
T m_SynthEPhs ;
T m_SynthELayer ;
T m_SynthF ;
T m_SynthFType ;
T m_SynthFSkew ;
T m_SynthFFrq ;
T m_SynthFPhs ;
T m_SynthFLayer ;
} ;
# define CACHE_NUM 10
# define CACHE_WIDTH 21
# define VORONOI_MAXPOINTS 10
/// <summary>
/// crackle.
/// </summary>
template < typename T >
class CrackleVariation : public ParametricVariation < T >
{
public :
CrackleVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " crackle " , eVariationId : : VAR_CRACKLE , weight )
{
Init ( ) ;
}
PARVARCOPY ( CrackleVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
int i = 0 ;
T l , r , trgL ;
v2T u , dO ;
glm : : ivec2 cv ;
v2T p [ VORONOI_MAXPOINTS ] = { v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) , v2T ( 0 ) } ;
if ( m_CellSize = = 0 )
return ;
T blurr = ( rand . Frand01 < T > ( ) + rand . Frand01 < T > ( ) ) / 2 + ( rand . Frand01 < T > ( ) - T ( 0.5 ) ) / 4 ;
T theta = M_2PI * rand . Frand01 < T > ( ) ;
u . x = blurr * std : : sin ( theta ) ;
u . y = blurr * std : : cos ( theta ) ;
--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
cv . x = int ( Floor ( u . x / m_HalfCellSize ) ) ;
cv . y = int ( Floor ( u . y / m_HalfCellSize ) ) ;
2023-04-25 19:59:54 -04:00
for ( int di = - 1 ; di < 2 ; di + + )
{
for ( int dj = - 1 ; dj < 2 ; dj + + )
{
CachedPosition ( m_C , cv . x + di , cv . y + dj , m_Z , m_HalfCellSize , m_Distort , p [ i ] ) ;
i + + ;
}
}
int q = m_VarFuncs - > Closest ( p , 9 , u ) ;
static glm : : ivec2 offset [ 9 ] = { { - 1 , - 1 } , { - 1 , 0 } , { - 1 , 1 } ,
{ 0 , - 1 } , { 0 , 0 } , { 0 , 1 } ,
{ 1 , - 1 } , { 1 , 0 } , { 1 , 1 }
} ;
cv + = offset [ q ] ;
i = 0 ;
for ( int di = - 1 ; di < 2 ; di + + )
{
for ( int dj = - 1 ; dj < 2 ; dj + + )
{
CachedPosition ( m_C , cv . x + di , cv . y + dj , m_Z , m_HalfCellSize , m_Distort , p [ i ] ) ;
i + + ;
}
}
l = m_VarFuncs - > Voronoi ( p , 9 , 4 , u ) ;
dO = u - p [ 4 ] ;
trgL = std : : pow ( std : : abs ( Zeps < T > ( l ) ) , m_Power ) * m_Scale ;
r = trgL / Zeps < T > ( l ) ;
dO * = r ;
dO + = p [ 4 ] ;
helper . Out . x = m_Weight * dO . x ;
helper . Out . y = m_Weight * dO . y ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Zeps " , " Sqr " , " Closest " , " Vratio " , " Voronoi " , " SimplexNoise3D " } ;
}
virtual vector < string > OpenCLGlobalDataNames ( ) const override
{
return vector < string > { " NOISE_INDEX " , " NOISE_POINTS " , " OFFSETS " } ;
}
virtual string OpenCLFuncsString ( ) const override
{
ostringstream os ;
os < <
" static void Position(__constant real_t* cache, __global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v) \n "
" { \n "
" if (abs(x) <= " < < CACHE_NUM < < " && abs(y) <= " < < CACHE_NUM < < " ) \n "
" { \n "
" int index = (((x + " < < CACHE_NUM < < " ) * " < < CACHE_WIDTH < < " ) + (y + " < < CACHE_NUM < < " )) * 2; \n "
" (*v).x = cache[index]; \n "
" (*v).y = cache[index + 1]; \n "
" } \n "
" else \n "
" { \n "
" real4 e, f; \n "
" e.x = x * 2.5; \n "
" e.y = y * 2.5; \n "
" e.z = z * 2.5; \n "
" f.x = fma((real_t)y, (real_t)(2.5), (real_t)( 30.2)); \n "
" f.y = fma((real_t)x, (real_t)(2.5), (real_t)(-12.1)); \n "
" f.z = fma(z, (real_t)(2.5), (real_t)(19.8)); \n "
" (*v).x = fma(d, SimplexNoise3D(&e, p, grad), (real_t)y) * s; \n "
" (*v).y = fma(d, SimplexNoise3D(&f, p, grad), (real_t)x) * s; \n "
" } \n "
" } \n "
" \n " ;
return os . str ( ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss , ss2 ;
intmax_t i = 0 ;
ss2 < < " _ " < < XformIndexInEmber ( ) ;
string weight = WeightDefineString ( ) ;
string index = ss2 . str ( ) + " ] " ;
string cellSize = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string power = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string distort = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scale = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string z = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string halfCellSize = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cache = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t int di = -1, dj = -1; \n "
< < " \t \t int i = 0; \n "
< < " \t \t real_t l, r, trgL; \n "
< < " \t \t real2 u, dO; \n "
< < " \t \t int2 cv; \n "
< < " \t \t real2 p[ " < < VORONOI_MAXPOINTS < < " ]; \n "
< < " \t \t __global real2* offset = (__global real2*)(globalShared + OFFSETS); \n "
< < " \n "
< < " \t \t if ( " < < cellSize < < " == 0) \n "
< < " \t \t return; \n "
< < " \n "
< < " \t \t real_t blurr = (MwcNext01(mwc) + MwcNext01(mwc)) / 2 + (MwcNext01(mwc) - 0.5) / 4; \n "
< < " \t \t real_t theta = M_2PI * MwcNext01(mwc); \n "
< < " \t \t u.x = blurr * sin(theta); \n "
< < " \t \t u.y = blurr * cos(theta); \n "
< < " \t \t cv.x = (int)floor(u.x / " < < halfCellSize < < " ); \n "
< < " \t \t cv.y = (int)floor(u.y / " < < halfCellSize < < " ); \n "
< < " \n "
< < " \t \t for (di = -1; di < 2; di++) \n "
< < " \t \t { \n "
< < " \t \t for (dj = -1; dj < 2; dj++) \n "
< < " \t \t { \n "
< < " \t \t Position(& " < < cache < < " , globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " < < z < < " , " < < halfCellSize < < " , " < < distort < < " , &p[i]); \n "
< < " \t \t i++; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t int q = Closest(p, 9, &u); \n "
< < " \t \t cv.x += (int)offset[q].x; \n "
< < " \t \t cv.y += (int)offset[q].y; \n "
< < " \t \t i = 0; \n "
< < " \n "
< < " \t \t for (di = -1; di < 2; di++) \n "
< < " \t \t { \n "
< < " \t \t for (dj = -1; dj < 2; dj++) \n "
< < " \t \t { \n "
< < " \t \t Position(& " < < cache < < " , globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " < < z < < " , " < < halfCellSize < < " , " < < distort < < " , &p[i]); \n "
< < " \t \t i++; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t l = Zeps(Voronoi(p, 9, 4, &u)); \n "
< < " \t \t dO = u - p[4]; \n "
< < " \t \t trgL = pow(fabs(l), " < < power < < " ) * " < < scale < < " ; \n "
< < " \t \t r = trgL / l; \n "
< < " \t \t dO *= r; \n "
< < " \t \t dO += p[4]; \n "
< < " \t \t vOut.x = " < < weight < < " * dO.x; \n "
< < " \t \t vOut.y = " < < weight < < " * dO.y; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_HalfCellSize = Zeps < T > ( std : : abs ( m_CellSize ) / 2 ) ;
for ( int x = - CACHE_NUM ; x < = CACHE_NUM ; x + + )
for ( int y = - CACHE_NUM ; y < = CACHE_NUM ; y + + )
Position ( x , y , m_Z , m_HalfCellSize , m_Distort , m_C [ x + CACHE_NUM ] [ y + CACHE_NUM ] ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . reserve ( 8 ) ;
m_Params . push_back ( ParamWithName < T > ( & m_CellSize , prefix + " crackle_cellsize " , 1 , eParamType : : REAL , T ( 0.0001 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Power , prefix + " crackle_power " , T ( 0.2 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Distort , prefix + " crackle_distort " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scale , prefix + " crackle_scale " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Z , prefix + " crackle_z " ) ) ;
--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_HalfCellSize , prefix + " crackle_half_cellsize " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & ( m_C [ 0 ] [ 0 ] . x ) , prefix + " crackle_cache " , sizeof ( m_C ) ) ) ;
}
private :
void Position ( int x , int y , T z , T s , T d , v2T & v )
{
v3T e , f ;
// Values here are arbitrary, chosen simply to be far enough apart so they do not correlate
e . x = x * T ( 2.5 ) ;
e . y = y * T ( 2.5 ) ;
e . z = z * T ( 2.5 ) ;
// Cross-over between x and y is intentional
f . x = y * T ( 2.5 ) + T ( 30.2 ) ;
f . y = x * T ( 2.5 ) - T ( 12.1 ) ;
f . z = z * T ( 2.5 ) + T ( 19.8 ) ;
v . x = ( x + d * m_VarFuncs - > SimplexNoise3D ( e ) ) * s ;
v . y = ( y + d * m_VarFuncs - > SimplexNoise3D ( f ) ) * s ;
}
void CachedPosition ( v2T cache [ CACHE_WIDTH ] [ CACHE_WIDTH ] , int x , int y , T z , T s , T d , v2T & v )
{
if ( std : : abs ( x ) < = CACHE_NUM & & std : : abs ( y ) < = CACHE_NUM )
v = cache [ x + CACHE_NUM ] [ y + CACHE_NUM ] ;
else
Position ( x , y , z , s , d , v ) ;
}
T m_CellSize ;
T m_Power ;
T m_Distort ;
T m_Scale ;
T m_Z ;
T m_HalfCellSize ; //Precalc
v2T m_C [ CACHE_WIDTH ] [ CACHE_WIDTH ] ; //Not kept as a precalc because it crashes Nvidia GPUs.
shared_ptr < VarFuncs < T > > m_VarFuncs = VarFuncs < T > : : Instance ( ) ;
} ;
/// <summary>
/// crackle2.
/// By tatasz.
/// </summary>
template < typename T >
class Crackle2Variation : public ParametricVariation < T >
{
public :
Crackle2Variation ( T weight = 1.0 ) : ParametricVariation < T > ( " crackle2 " , eVariationId : : VAR_CRACKLE2 , weight )
{
Init ( ) ;
}
PARVARCOPY ( Crackle2Variation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T seed = 34554 ;
v2T cell ( Floor ( helper . In . x ) , Floor ( helper . In . y ) ) ;
v2T xy0 ( cell . x + m_OneOverCellsize * VarFuncs < T > : : HashShadertoy ( cell . x , cell . y , seed ) , cell . y + m_OneOverCellsize * VarFuncs < T > : : HashShadertoy ( cell . y , cell . x * 3 , seed + 7 ) ) ;
v2T xy1_aux ;
if ( rand . Frand01 < T > ( ) < 0.5 )
{
if ( rand . Frand01 < T > ( ) < 0.5 )
xy1_aux = v2T ( cell . x , cell . y + 1 ) ;
else
xy1_aux = v2T ( cell . x , cell . y - 1 ) ;
}
else
{
if ( rand . Frand01 < T > ( ) < 0.5 )
xy1_aux = v2T ( cell . x + 1 , cell . y ) ;
else
xy1_aux = v2T ( cell . x - 1 , cell . y ) ;
}
v2T xy1 ( xy1_aux . x + m_OneOverCellsize * VarFuncs < T > : : HashShadertoy ( xy1_aux . x , xy1_aux . y , seed ) , xy1_aux . y + m_OneOverCellsize * VarFuncs < T > : : HashShadertoy ( xy1_aux . y , xy1_aux . x * 3 , seed + 7 ) ) ;
v2T v = xy1 - xy0 ;
v2T result = ( xy0 + v * rand . Frand01 < T > ( ) ) * m_Cellsize ;
helper . Out . x = result . x ;
helper . Out . y = result . 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 cellsize = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string oneovercellsize = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t seed = 34554.0; \n "
< < " \t \t real2 cell = (real2)(floor(vIn.x), floor(vIn.y)); \n "
< < " \t \t real2 xy0 = (real2)(cell.x + " < < oneovercellsize < < " * HashShadertoy(cell.x, cell.y, seed), cell.y + " < < oneovercellsize < < " * HashShadertoy(cell.y, cell.x * 3.0, seed + 7.0)); \n "
< < " \t \t real2 xy1_aux; \n "
< < " \t \t \n "
< < " \t \t if (MwcNext01(mwc) < 0.5) \n "
< < " \t \t { \n "
< < " \t \t if (MwcNext01(mwc) < 0.5) \n "
< < " \t \t xy1_aux = (real2)(cell.x, cell.y + 1); \n "
< < " \t \t else \n "
< < " \t \t xy1_aux = (real2)(cell.x, cell.y - 1); \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if (MwcNext01(mwc) < 0.5) \n "
< < " \t \t xy1_aux = (real2)(cell.x + 1, cell.y); \n "
< < " \t \t else \n "
< < " \t \t xy1_aux = (real2)(cell.x - 1, cell.y); \n "
< < " \t \t } \n "
< < " \t \t \n "
< < " \t \t real2 xy1 = (real2)(xy1_aux.x + " < < oneovercellsize < < " * HashShadertoy(xy1_aux.x, xy1_aux.y, seed), xy1_aux.y + " < < oneovercellsize < < " * HashShadertoy(xy1_aux.y, xy1_aux.x * 3.0, seed + 7.0)); \n "
< < " \t \t real2 v = xy1 - xy0; \n "
< < " \t \t real2 result = (xy0 + v * MwcNext01(mwc)) * " < < cellsize < < " ; \n "
< < " \t \t vOut.x = result.x; \n "
< < " \t \t vOut.y = result.y; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Fract " , " HashShadertoy " } ;
}
virtual void Precalc ( ) override
{
m_OneOverCellsize = 1 / Zeps ( m_Cellsize ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Cellsize , prefix + " crackle2_cellsize " , 1 , eParamType : : REAL , T ( 0.0001 ) ) ) ;
--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_OneOverCellsize , prefix + " crackle2_one_over_cellsize " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
}
private :
T m_Cellsize ;
T m_OneOverCellsize ;
} ;
/// <summary>
/// post_smartcrop.
/// This variation is special in that it only exists as a post_.
/// </summary>
template < typename T >
class PostSmartcropVariation : public ParametricVariation < T >
{
public :
PostSmartcropVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " post_smartcrop " , eVariationId : : VAR_POST_SMARTCROP , weight )
{
m_PrePostAssignType = eVariationAssignType : : ASSIGNTYPE_SET ;
m_VarType = eVariationType : : VARTYPE_POST ; //Very special usage, post only.
Init ( ) ;
}
PARVARCOPY ( PostSmartcropVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
bool lastPart = true ;
T xi , yi , zi ;
int iMode = int ( m_Mode ) ;
if ( m_Static > 1 )
{
xi = helper . In . x ;
yi = helper . In . y ;
zi = helper . In . z ;
}
else //Extremely strange usage, where a post variation wants the original affine transformed points.
{
xi = helper . m_TransX ;
yi = helper . m_TransY ;
zi = helper . m_TransZ ;
}
T ang = std : : atan2 ( yi , xi ) ;
T rad = std : : sqrt ( SQR ( xi ) + SQR ( yi ) ) ;
if ( m_Radial )
{
T edge = m_Edge * ( rand . Frand01 < T > ( ) - T ( 0.5 ) ) ;
T xang = ang / M_2PI + 1 + edge ;
xang = ( xang - int ( xang ) ) * M_2PI ;
if ( int ( xang > m_WorkPower ) = = iMode )
{
if ( m_Cropmode = = 2 )
{
if ( m_Static > 1 | | m_Static = = - 1 )
{
helper . Out . x = m_X ; //This is post only with an assign type of SET, so no need to set m_* to 0 after these (or any other) direct assignments.
helper . Out . y = m_Y ;
helper . Out . z = m_Z ;
}
else
{
helper . Out . x = helper . In . x + m_X ; //Original specifically summed the running sum point.
helper . Out . y = helper . In . y + m_Y ;
helper . Out . z = helper . In . z + m_Z ;
}
outPoint . m_ColorX = m_C ;
}
else
{
T x , s , c ;
x = int ( rand . Frand01 < T > ( ) * 2 ) ? m_WorkPower + ( rand . Frand01 < T > ( ) * m_Scatter + m_Offset + edge ) * T ( M_PI ) : - ( rand . Frand01 < T > ( ) * m_Scatter + m_Offset + edge ) * T ( M_PI ) ;
sincos ( x , & s , & c ) ;
if ( m_Static > 1 | | m_Static = = - 1 )
{
helper . Out . x = m_Weight * rad * c ;
helper . Out . y = m_Weight * rad * s ;
helper . Out . z = m_Weight * zi ;
}
else
{
helper . Out . x = helper . In . x + ( m_Weight * rad * c ) ; //Original specifically summed the running sum point.
helper . Out . y = helper . In . y + ( m_Weight * rad * s ) ;
helper . Out . z = helper . In . z + ( m_Weight * zi ) ;
}
}
lastPart = false ;
}
}
else
{
T coeff ;
if ( m_Distortion = = 0 )
{
coeff = 1 ;
}
else
{
T xang = ( ang + T ( M_PI ) ) / m_Alpha ;
xang = xang - int ( xang ) ;
xang = ( xang < T ( 0.5 ) ) ? xang : 1 - xang ;
coeff = 1 / std : : cos ( xang * m_Alpha ) ;
if ( m_Roundstr ! = 0 )
{
T wwidth = ( ( m_Roundwidth ! = 1 ) ? std : : exp ( std : : log ( xang * 2 ) * m_Roundwidth ) : ( xang * 2 ) ) * m_RoundCoeff ;
coeff = std : : abs ( ( 1 - wwidth ) * coeff + wwidth ) ;
}
if ( m_Distortion ! = 1 )
coeff = std : : exp ( std : : log ( coeff ) * m_Distortion ) ;
}
T xr = coeff * ( ( m_Edge ! = 0 ) ? m_WorkRadius + m_Edge * ( rand . Frand01 < T > ( ) - T ( 0.5 ) ) : m_WorkRadius ) ;
if ( ( rad > xr ) = = iMode )
{
if ( m_Cropmode )
{
if ( m_Cropmode = = 2 )
{
if ( m_Static > 1 | | m_Static = = - 1 )
{
helper . Out . x = m_X ;
helper . Out . y = m_Y ;
helper . Out . z = m_Z ;
}
else
{
helper . Out . x = helper . In . x + m_X ; //Original specifically summed the running sum point.
helper . Out . y = helper . In . y + m_Y ;
helper . Out . z = helper . In . z + m_Z ;
}
outPoint . m_ColorX = m_C ;
}
else
{
T rdc = ( m_Cropmode = = - 1 ) ? rad : xr + coeff * ( rand . Frand01 < T > ( ) * m_Scatter + m_Offset ) ;
T x , s , c ;
x = ang + m_WorkRotation ;
sincos ( x , & s , & c ) ;
if ( m_Static > 1 | | m_Static = = - 1 )
{
helper . Out . x = m_Weight * rdc * c ;
helper . Out . y = m_Weight * rdc * s ;
helper . Out . z = m_Weight * zi ;
}
else
{
helper . Out . x = helper . In . x + ( m_Weight * rdc * c ) ;
helper . Out . y = helper . In . y + ( m_Weight * rdc * s ) ;
helper . Out . z = helper . In . z + ( m_Weight * zi ) ;
}
}
}
else
{
if ( m_Static > 1 | | m_Static = = - 1 )
{
helper . Out . x = 0 ;
helper . Out . y = 0 ;
helper . Out . z = 0 ;
}
}
lastPart = false ;
}
}
if ( lastPart )
{
if ( m_Static = = 3 )
{
m_X = m_Weight * helper . m_TransX ; //Another case where it wants the original affine transformed points.
m_Y = m_Weight * helper . m_TransY ;
m_Z = m_Weight * helper . m_TransZ ;
}
else
{
m_X = m_Weight * xi ;
m_Y = m_Weight * yi ;
m_Z = m_Weight * zi ;
}
if ( m_Cropmode = = 2 )
m_C = outPoint . m_ColorX ;
if ( m_Static > 0 )
{
helper . Out . x = m_X ;
helper . Out . y = m_Y ;
helper . Out . z = m_Z ;
}
else
{
helper . Out . x = helper . In . x + m_X ; //Original specifically summed the running sum point.
helper . Out . y = helper . In . y + m_Y ;
helper . Out . z = helper . In . z + m_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 power = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string radius = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string roundstr = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string roundwidth = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string distortion = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string edge = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string scatter = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string offset = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string rotation = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string cropmode = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string staticc = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string mode = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string radial = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string workradius = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string workpower = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string alpha = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string roundcoeff = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string workrotation = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string x = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ; //State.
string y = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
string z = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
string c = " varState-> " + m_Params [ i + + ] . Name ( ) + stateIndex ;
ss < < " \t { \n "
< < " \t \t int lastPart = 1; \n "
< < " \t \t real_t xi, yi, zi; \n "
< < " \t \t int iMode = (int) " < < mode < < " ; \n "
< < " \n "
< < " \t \t if ( " < < staticc < < " > 1) \n "
< < " \t \t { \n "
< < " \t \t xi = vIn.x; \n "
< < " \t \t yi = vIn.y; \n "
< < " \t \t zi = vIn.z; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t xi = transX; \n "
< < " \t \t yi = transY; \n "
< < " \t \t zi = transZ; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t real_t ang = atan2(yi, xi); \n "
< < " \t \t real_t rad = sqrt(SQR(xi) + SQR(yi)); \n "
< < " \n "
< < " \t \t if ( " < < radial < < " ) \n "
< < " \t \t { \n "
< < " \t \t real_t edge = " < < edge < < " * (MwcNext01(mwc) - 0.5); \n "
< < " \t \t real_t xang = ang / M_2PI + 1 + edge; \n "
< < " \t \t xang = (xang - (int)xang) * M_2PI; \n "
< < " \n "
< < " \t \t if ((int)(xang > " < < workpower < < " ) == iMode) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < cropmode < < " == 2) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < staticc < < " > 1 || " < < staticc < < " == -1) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < x < < " ; \n "
< < " \t \t vOut.y = " < < y < < " ; \n "
< < " \t \t vOut.z = " < < z < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x + " < < x < < " ; \n "
< < " \t \t vOut.y = vIn.y + " < < y < < " ; \n "
< < " \t \t vOut.z = vIn.z + " < < z < < " ; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t outPoint->m_ColorX = " < < c < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t x, s, c; \n "
< < " \t \t x = ((int)(MwcNext01(mwc) * 2)) ? " < < workpower < < " + (MwcNext01(mwc) * " < < scatter < < " + " < < offset < < " + edge) * MPI : -(MwcNext01(mwc) * " < < scatter < < " + " < < offset < < " + edge) * MPI; \n "
< < " \t \t s = sincos(x, &c); \n "
< < " \n "
< < " \t \t if ( " < < staticc < < " > 1 || " < < staticc < < " == -1) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < weight < < " * rad * c; \n "
< < " \t \t vOut.y = " < < weight < < " * rad * s; \n "
< < " \t \t vOut.z = " < < weight < < " * zi; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x + ( " < < weight < < " * rad * c); \n "
< < " \t \t vOut.y = vIn.y + ( " < < weight < < " * rad * s); \n "
< < " \t \t vOut.z = vIn.z + ( " < < weight < < " * zi); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t lastPart = 0; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t coeff; \n "
< < " \n "
< < " \t \t if ( " < < distortion < < " == 0) \n "
< < " \t \t { \n "
< < " \t \t coeff = 1; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t xang = (ang + MPI) / " < < alpha < < " ; \n "
< < " \t \t xang = xang - (int)xang; \n "
< < " \t \t xang = (xang < 0.5) ? xang : 1 - xang; \n "
< < " \t \t coeff = 1 / cos(xang * " < < alpha < < " ); \n "
< < " \n "
< < " \t \t if ( " < < roundstr < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t real_t wwidth = (( " < < roundwidth < < " != 1) ? exp(log(xang * 2) * " < < roundwidth < < " ) : (xang * 2)) * " < < roundcoeff < < " ; \n "
< < " \t \t coeff = fabs((1 - wwidth) * coeff + wwidth); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < distortion < < " != 1) \n "
< < " \t \t coeff = exp(log(coeff) * " < < distortion < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t real_t xr = coeff * (( " < < edge < < " != 0) ? " < < workradius < < " + " < < edge < < " * (MwcNext01(mwc) - 0.5) : " < < workradius < < " ); \n "
< < " \n "
< < " \t \t if ((int)(rad > xr) == iMode) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < cropmode < < " ) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < cropmode < < " == 2) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < staticc < < " > 1 || " < < staticc < < " == -1) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < x < < " ; \n "
< < " \t \t vOut.y = " < < y < < " ; \n "
< < " \t \t vOut.z = " < < z < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x + " < < x < < " ; \n "
< < " \t \t vOut.y = vIn.y + " < < y < < " ; \n "
< < " \t \t vOut.z = vIn.z + " < < z < < " ; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t outPoint->m_ColorX = " < < c < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t real_t rdc = ( " < < cropmode < < " == -1) ? rad : xr + coeff * (MwcNext01(mwc) * " < < scatter < < " + " < < offset < < " ); \n "
< < " \t \t real_t x, s, c; \n "
< < " \t \t x = ang + " < < workrotation < < " ; \n "
< < " \t \t s = sincos(x, &c); \n "
< < " \n "
< < " \t \t if ( " < < staticc < < " > 1 || " < < staticc < < " == -1) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < weight < < " * rdc * c; \n "
< < " \t \t vOut.y = " < < weight < < " * rdc * s; \n "
< < " \t \t vOut.z = " < < weight < < " * zi; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x + ( " < < weight < < " * rdc * c); \n "
< < " \t \t vOut.y = vIn.y + ( " < < weight < < " * rdc * s); \n "
< < " \t \t vOut.z = vIn.z + ( " < < weight < < " * zi); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t if ( " < < staticc < < " > 1 || " < < staticc < < " == -1) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = 0; \n "
< < " \t \t vOut.y = 0; \n "
< < " \t \t vOut.z = 0; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t lastPart = 0; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if (lastPart) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < staticc < < " == 3) \n "
< < " \t \t { \n "
< < " \t \t " < < x < < " = " < < weight < < " * transX; \n "
< < " \t \t " < < y < < " = " < < weight < < " * transY; \n "
< < " \t \t " < < z < < " = " < < weight < < " * transZ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t " < < x < < " = " < < weight < < " * xi; \n "
< < " \t \t " < < y < < " = " < < weight < < " * yi; \n "
< < " \t \t " < < z < < " = " < < weight < < " * zi; \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < cropmode < < " == 2) \n "
< < " \t \t " < < c < < " = outPoint->m_ColorX; \n "
< < " \n "
< < " \t \t if ( " < < staticc < < " > 0) \n "
< < " \t \t { \n "
< < " \t \t vOut.x = " < < x < < " ; \n "
< < " \t \t vOut.y = " < < y < < " ; \n "
< < " \t \t vOut.z = " < < z < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t vOut.x = vIn.x + " < < x < < " ; \n "
< < " \t \t vOut.y = vIn.y + " < < y < < " ; \n "
< < " \t \t vOut.z = vIn.z + " < < z < < " ; \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual void Precalc ( ) override
{
m_Mode = T ( ( ( m_Power > 0 ) = = ( m_Radius > 0 ) ) ? 1 : 0 ) ;
m_WorkRadius = std : : abs ( m_Radius ) ;
m_WorkPower = std : : abs ( Zeps < T > ( m_Power ) ) ;
if ( m_WorkPower < 2 )
{
m_WorkPower = m_WorkPower * T ( M_PI ) ;
m_Radial = 1 ;
}
else
{
m_Radial = 0 ;
m_Alpha = M_2PI / m_WorkPower ;
m_RoundCoeff = m_Roundstr / Zeps < T > ( std : : sin ( m_Alpha / 2 ) ) / m_WorkPower * 2 ;
m_WorkRotation = m_Rotation * m_Alpha ;
}
m_X = m_Y = m_Z = m_C = 0 ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
--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 + " smartcrop_power " , 4 ) ) ; //Original used a prefix of scrop_, which is incompatible with Ember's design.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( & m_Radius , prefix + " smartcrop_radius " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Roundstr , prefix + " smartcrop_roundstr " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Roundwidth , prefix + " smartcrop_roundwidth " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Distortion , prefix + " smartcrop_distortion " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Edge , prefix + " smartcrop_edge " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Scatter , prefix + " smartcrop_scatter " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Offset , prefix + " smartcrop_offset " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Rotation , prefix + " smartcrop_rotation " ) ) ;
--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_Cropmode , prefix + " smartcrop_cropmode " , 1 , eParamType : : REAL , - 1 , 2 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Static , prefix + " smartcrop_static " , 1 , eParamType : : REAL , - 1 , 3 ) ) ;
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_Mode , prefix + " smartcrop_mode " ) ) ; //Precalc.
m_Params . push_back ( ParamWithName < T > ( true , & m_Radial , prefix + " smartcrop_radial " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_WorkRadius , prefix + " smartcrop_work_radius " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_WorkPower , prefix + " smartcrop_work_power " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_Alpha , prefix + " smartcrop_alpha " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_RoundCoeff , prefix + " smartcrop_round_coeff " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_WorkRotation , prefix + " smartcrop_work_rotation " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_X , prefix + " smartcrop_x " ) ) ; //State.
m_Params . push_back ( ParamWithName < T > ( true , true , & m_Y , prefix + " smartcrop_y " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_Z , prefix + " smartcrop_z " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , true , & m_C , prefix + " smartcrop_c " ) ) ;
}
private :
T m_Power ;
T m_Radius ;
T m_Roundstr ;
T m_Roundwidth ;
T m_Distortion ;
T m_Edge ;
T m_Scatter ;
T m_Offset ;
T m_Rotation ;
T m_Cropmode ;
T m_Static ;
T m_Mode ; //Precalc.
T m_Radial ;
T m_WorkRadius ;
T m_WorkPower ;
T m_Alpha ;
T m_RoundCoeff ;
T m_WorkRotation ;
T m_X ; //State.
T m_Y ;
T m_Z ;
T m_C ;
} ;
/// <summary>
/// erf.
/// </summary>
template < typename T >
class ErfVariation : public Variation < T >
{
public :
ErfVariation ( T weight = 1.0 ) : Variation < T > ( " erf " , eVariationId : : VAR_ERF , weight ) { }
VARCOPY ( ErfVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
helper . Out . x = m_Weight * std : : erf ( helper . In . x ) ;
helper . Out . y = m_Weight * std : : erf ( helper . In . y ) ;
helper . Out . z = DefaultZ ( helper ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss ;
string weight = WeightDefineString ( ) ;
ss < < " \t { \n "
< < " \t \t vOut.x = " < < weight < < " * erf(vIn.x); \n "
< < " \t \t vOut.y = " < < weight < < " * erf(vIn.y); \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
} ;
/// <summary>
/// xerf.
/// </summary>
template < typename T >
class XerfVariation : public Variation < T >
{
public :
XerfVariation ( T weight = 1.0 ) : Variation < T > ( " xerf " , eVariationId : : VAR_XERF , weight , true ) { }
VARCOPY ( XerfVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T r2 = Sqr ( std : : sqrt ( helper . m_PrecalcSumSquares + SQR ( helper . In . z ) ) ) ;
helper . Out . x = m_Weight * ( std : : abs ( helper . In . x ) > = 2 ? helper . In . x / r2 : std : : erf ( helper . In . x ) ) ;
helper . Out . y = m_Weight * ( std : : abs ( helper . In . y ) > = 2 ? helper . In . y / r2 : std : : erf ( helper . In . y ) ) ;
helper . Out . z = m_Weight * ( std : : abs ( helper . In . z ) > = 2 ? helper . In . z / r2 : std : : erf ( helper . In . z ) ) ;
}
virtual string OpenCLString ( ) const override
{
ostringstream ss ;
string weight = WeightDefineString ( ) ;
ss < < " \t { \n "
< < " \t \t real_t r2 = Sqr(sqrt(fma(vIn.z, vIn.z, precalcSumSquares))); \n "
< < " \t \t vOut.x = " < < weight < < " * (fabs(vIn.x) >= 2 ? vIn.x / r2 : erf(vIn.x)); \n "
< < " \t \t vOut.y = " < < weight < < " * (fabs(vIn.y) >= 2 ? vIn.y / r2 : erf(vIn.y)); \n "
< < " \t \t vOut.z = " < < weight < < " * (fabs(vIn.z) >= 2 ? vIn.z / r2 : erf(vIn.z)); \n "
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " } ;
}
} ;
template < typename T >
class WVariation : public ParametricVariation < T >
{
public :
WVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " w " , eVariationId : : VAR_W , weight , true , true , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( WVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T a = helper . m_PrecalcAtanyx ;
T r = helper . m_PrecalcSqrtSumSquares ;
T a2 = a + m_Angle ;
if ( a2 < - T ( M_PI ) )
a2 + = M_2PI ;
if ( a2 > T ( M_PI ) )
a2 - = M_2PI ;
T s , c ;
T total = 0 ;
T total2 = 0 ;
T temp1 , temp2 , temp4 ;
if ( m_Hypergon ! = 0 )
{
temp1 = fmod ( std : : abs ( a ) , M_2PI / m_HypergonN ) - T ( M_PI ) / m_HypergonN ;
temp2 = Sqr ( std : : tan ( temp1 ) ) + 1 ;
if ( temp2 > = Sqr ( m_HypergonD ) )
{
total + = m_Hypergon ;
}
else
{
total + = m_Hypergon * ( m_HypergonD - std : : sqrt ( Sqr ( m_HypergonD ) - temp2 ) ) / std : : sqrt ( temp2 ) ;
}
}
if ( m_Star ! = 0 )
{
temp1 = std : : tan ( std : : abs ( fmod ( std : : abs ( a ) , M_2PI / m_StarN ) - T ( M_PI ) / m_StarN ) ) ;
total + = m_Star * std : : sqrt ( Sqr ( m_TanStarSlope ) * ( 1 + Sqr ( temp1 ) ) / Sqr ( temp1 + m_TanStarSlope ) ) ;
}
if ( m_Lituus ! = 0 )
{
total + = m_Lituus * std : : pow ( std : : abs ( a / T ( M_PI ) + 1 ) , m_InvLituusA ) ;
}
if ( m_Super ! = 0 )
{
temp4 = a * m_SuperM4th ;
sincos ( temp4 , & s , & c ) ;
total + = m_Super * std : : pow ( std : : pow ( std : : abs ( c ) , m_SuperN2 ) + std : : pow ( std : : abs ( s ) , m_SuperN3 ) , m_OneOverSuperN1 ) ;
}
if ( r < = total )
{
if ( m_Hypergon ! = 0.0 )
{
temp1 = fmod ( std : : abs ( a2 ) , M_2PI / m_HypergonN ) - T ( M_PI ) / m_HypergonN ;
temp2 = Sqr ( std : : tan ( temp1 ) ) + 1 ;
if ( temp2 > = Sqr ( m_HypergonD ) )
{
total2 + = m_Hypergon ;
}
else
{
total2 + = m_Hypergon * ( m_HypergonD - std : : sqrt ( Sqr ( m_HypergonD ) - temp2 ) ) / std : : sqrt ( temp2 ) ;
}
}
if ( m_Star ! = 0 )
{
temp1 = std : : tan ( std : : abs ( fmod ( std : : abs ( a2 ) , M_2PI / m_StarN ) - T ( M_PI ) / m_StarN ) ) ;
total2 + = m_Star * std : : sqrt ( Sqr ( m_TanStarSlope ) * ( 1 + Sqr ( temp1 ) ) / Sqr ( temp1 + m_TanStarSlope ) ) ;
}
if ( m_Lituus ! = 0 )
{
total2 + = m_Lituus * std : : pow ( std : : abs ( a2 / T ( M_PI ) + 1 ) , m_InvLituusA ) ;
}
if ( m_Super ! = 0 )
{
temp4 = a2 * m_SuperM4th ;
sincos ( temp4 , & s , & c ) ;
total2 + = m_Super * std : : pow ( std : : pow ( std : : abs ( c ) , m_SuperN2 ) + std : : pow ( std : : abs ( s ) , m_SuperN3 ) , m_OneOverSuperN1 ) ;
}
r = m_Weight * total2 * r / total ;
sincos ( a2 , & s , & c ) ;
helper . Out . x = r * c ;
helper . Out . y = r * s ;
}
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 angle = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergon = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonR = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string star = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituus = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string super = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invLituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc
string tanStarSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonD = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM4th = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string oneOverSuperN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t a = precalcAtanyx; \n "
< < " \t \t real_t r = precalcSqrtSumSquares; \n "
< < " \t \t real_t a2 = a + " < < angle < < " ; \n "
< < " \n "
< < " \t \t if (a2 < -MPI) \n "
< < " \t \t a2 += M_2PI; \n "
< < " \n "
< < " \t \t if (a2 > MPI) \n "
< < " \t \t a2 -= M_2PI; \n "
< < " \n "
< < " \t \t real_t s, c; \n "
< < " \t \t real_t total = 0; \n "
< < " \t \t real_t total2 = 0; \n "
< < " \t \t real_t temp1, temp2, temp4; \n "
< < " \n "
< < " \t \t if ( " < < hypergon < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = fmod(fabs(a), (real_t)M_2PI / " < < hypergonN < < " ) - MPI / " < < hypergonN < < " ; \n "
< < " \t \t temp2 = Sqr(tan(temp1)) + 1; \n "
< < " \n "
< < " \t \t if (temp2 >= Sqr( " < < hypergonD < < " )) \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " * ( " < < hypergonD < < " - sqrt(fma( " < < hypergonD < < " , " < < hypergonD < < " , -temp2))) / sqrt(temp2); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < star < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = tan(fabs(fmod(fabs(a), (real_t)M_2PI / " < < starN < < " ) - MPI / " < < starN < < " )); \n "
< < " \t \t total += " < < star < < " * sqrt(Sqr( " < < tanStarSlope < < " ) * fma(temp1, temp1, (real_t)(1.0)) / Sqr(temp1 + " < < tanStarSlope < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < lituus < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t total += " < < lituus < < " * pow(fabs(a / MPI + 1), " < < invLituusA < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < super < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp4 = a * " < < superM4th < < " ; \n "
< < " \t \t s = sincos(temp4, &c); \n "
< < " \t \t total += " < < super < < " * pow(pow(fabs(c), " < < superN2 < < " ) + pow(fabs(s), " < < superN3 < < " ), " < < oneOverSuperN1 < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if (r <= total) \n "
< < " \t \t { \n "
< < " \t \t if ( " < < hypergon < < " != 0.0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = fmod(fabs(a2), (real_t)M_2PI / " < < hypergonN < < " ) - MPI / " < < hypergonN < < " ; \n "
< < " \t \t real_t tantemp = tan(temp1); \n "
< < " \t \t temp2 = fma(tantemp, tantemp, (real_t)(1.0)); \n "
< < " \n "
< < " \t \t if (temp2 >= Sqr( " < < hypergonD < < " )) \n "
< < " \t \t { \n "
< < " \t \t total2 += " < < hypergon < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t total2 += " < < hypergon < < " * ( " < < hypergonD < < " - sqrt(fma( " < < hypergonD < < " , " < < hypergonD < < " , -temp2))) / sqrt(temp2); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < star < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = tan(fabs(fmod(fabs(a2), (real_t)M_2PI / " < < starN < < " ) - MPI / " < < starN < < " )); \n "
< < " \t \t total2 += " < < star < < " * sqrt(Sqr( " < < tanStarSlope < < " ) * fma(temp1, temp1, (real_t)(1.0)) / Sqr(temp1 + " < < tanStarSlope < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < lituus < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t total2 += " < < lituus < < " * pow(fabs(a2 / MPI + 1), " < < invLituusA < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < super < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp4 = a2 * " < < superM4th < < " ; \n "
< < " \t \t s = sincos(temp4, &c); \n "
< < " \t \t total2 += " < < super < < " * pow(pow(fabs(c), " < < superN2 < < " ) + pow(fabs(s), " < < superN3 < < " ), " < < oneOverSuperN1 < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t r = " < < weight < < " * total2 * r / total; \n "
< < " \t \t s = sincos(a2, &c); \n "
< < " \t \t vOut.x = r * c; \n "
< < " \t \t vOut.y = r * s; \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 vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " } ;
}
virtual void Precalc ( ) override
{
m_HypergonD = std : : sqrt ( 1 + SQR ( m_HypergonR ) ) ;
m_InvLituusA = - m_LituusA ;
if ( IsClose ( m_StarSlope , T ( M_PI_2 ) ) )
m_TanStarSlope = std : : tan ( m_StarSlope - T ( 0.05 ) ) ; //Original did not do this, but it makes no sense to take tan(pi/2) because it's undefined.
else
m_TanStarSlope = std : : tan ( m_StarSlope ) ;
m_SuperM4th = m_SuperM / 4 ;
m_OneOverSuperN1 = - 1 / Zeps < T > ( m_SuperN1 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Angle , prefix + " w_angle " , 0 , eParamType : : REAL_CYCLIC , T ( - M_PI ) , T ( M_PI ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Hypergon , prefix + " w_hypergon " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonN , prefix + " w_hypergon_n " , 4 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonR , prefix + " w_hypergon_r " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Star , prefix + " w_star " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarN , prefix + " w_star_n " , 5 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarSlope , prefix + " w_star_slope " , 2 , eParamType : : REAL , EPS , T ( M_PI_2 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Lituus , prefix + " w_lituus " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_LituusA , prefix + " w_lituus_a " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Super , prefix + " w_super " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperM , prefix + " w_super_m " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN1 , prefix + " w_super_n1 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN2 , prefix + " w_super_n2 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN3 , prefix + " w_super_n3 " , 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_InvLituusA , prefix + " w_inv_lituus_a " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_TanStarSlope , prefix + " w_tan_star_slope " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HypergonD , prefix + " w_hypergon_d " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SuperM4th , prefix + " w_super_m_4th " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_OneOverSuperN1 , prefix + " w_one_over_super_n1 " ) ) ;
}
private :
T m_Angle ;
T m_Hypergon ;
T m_HypergonN ;
T m_HypergonR ;
T m_Star ;
T m_StarN ;
T m_StarSlope ;
T m_Lituus ;
T m_LituusA ;
T m_Super ;
T m_SuperM ;
T m_SuperN1 ;
T m_SuperN2 ;
T m_SuperN3 ;
T m_InvLituusA ; //Precalc
T m_TanStarSlope ;
T m_HypergonD ;
T m_SuperM4th ;
T m_OneOverSuperN1 ;
} ;
template < typename T >
class XVariation : public ParametricVariation < T >
{
public :
XVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " x " , eVariationId : : VAR_X , weight , true , false , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( XVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T a = helper . m_PrecalcAtanyx ;
T r ;
T s , c ;
T total = 0 ;
T temp1 , temp2 , temp4 ;
if ( m_Hypergon ! = 0 )
{
temp1 = fmod ( std : : abs ( a ) , M_2PI / m_HypergonN ) - T ( M_PI ) / m_HypergonN ;
temp2 = Sqr ( std : : tan ( temp1 ) ) + 1 ;
if ( temp2 > = Sqr ( m_HypergonD ) )
{
total + = m_Hypergon ;
}
else
{
total + = m_Hypergon * ( m_HypergonD - std : : sqrt ( Sqr ( m_HypergonD ) - temp2 ) ) / std : : sqrt ( temp2 ) ;
}
}
if ( m_Star ! = 0 )
{
temp1 = std : : tan ( std : : abs ( fmod ( std : : abs ( a ) , M_2PI / m_StarN ) - T ( M_PI ) / m_StarN ) ) ;
total + = m_Star * std : : sqrt ( Sqr ( m_TanStarSlope ) * ( 1 + Sqr ( temp1 ) ) / Sqr ( temp1 + m_TanStarSlope ) ) ;
}
if ( m_Lituus ! = 0 )
{
total + = m_Lituus * std : : pow ( std : : fabs ( a / T ( M_PI ) + 1 ) , m_InvLituusA ) ;
}
if ( m_Super ! = 0 )
{
temp4 = a * m_SuperM4th ;
sincos ( temp4 , & s , & c ) ;
total + = m_Super * std : : pow ( std : : pow ( std : : abs ( c ) , m_SuperN2 ) + std : : pow ( std : : abs ( s ) , m_SuperN3 ) , m_OneOverSuperN1 ) ;
}
r = m_Weight * std : : sqrt ( helper . m_PrecalcSumSquares + Sqr ( total ) ) ;
sincos ( a , & s , & c ) ;
helper . Out . x = r * c ;
helper . Out . y = r * s ;
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 hypergon = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonR = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string star = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituus = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string super = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invLituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc
string tanStarSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonD = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM4th = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string oneOverSuperN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t a = precalcAtanyx; \n "
< < " \t \t real_t r; \n "
< < " \t \t real_t s, c; \n "
< < " \t \t real_t total = 0; \n "
< < " \t \t real_t temp1, temp2, temp4; \n "
< < " \n "
< < " \t \t if ( " < < hypergon < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = fmod(fabs(a), M_2PI / " < < hypergonN < < " ) - MPI / " < < hypergonN < < " ; \n "
< < " \t \t real_t tantemp = tan(temp1); \n "
< < " \t \t temp2 = fma(tantemp, tantemp, (real_t)(1.0)); \n "
< < " \n "
< < " \t \t if (temp2 >= Sqr( " < < hypergonD < < " )) \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " * ( " < < hypergonD < < " - sqrt(fma( " < < hypergonD < < " , " < < hypergonD < < " , -temp2))) / sqrt(temp2); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < star < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = tan(fabs(fmod(fabs(a), M_2PI / " < < starN < < " ) - MPI / " < < starN < < " )); \n "
< < " \t \t total += " < < star < < " * sqrt(Sqr( " < < tanStarSlope < < " ) * fma(temp1, temp1, (real_t)(1.0)) / Sqr(temp1 + " < < tanStarSlope < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < lituus < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t total += " < < lituus < < " * pow(fabs(a / MPI + 1), " < < invLituusA < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < super < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp4 = a * " < < superM4th < < " ; \n "
< < " \t \t s = sincos(temp4, &c); \n "
< < " \t \t total += " < < super < < " * pow(pow(fabs(c), " < < superN2 < < " ) + pow(fabs(s), " < < superN3 < < " ), " < < oneOverSuperN1 < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t r = " < < weight < < " * sqrt(fma(total, total, precalcSumSquares)); \n "
< < " \t \t s = sincos(a, &c); \n "
< < " \t \t vOut.x = r * c; \n "
< < " \t \t vOut.y = r * s; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " } ;
}
virtual void Precalc ( ) override
{
m_HypergonD = std : : sqrt ( 1 + SQR ( m_HypergonR ) ) ;
m_InvLituusA = - m_LituusA ;
if ( IsClose ( m_StarSlope , T ( M_PI_2 ) ) )
m_TanStarSlope = std : : tan ( m_StarSlope - T ( 0.05 ) ) ; //Original did not do this, but it makes no sense to take tan(pi/2) because it's undefined.
else
m_TanStarSlope = std : : tan ( m_StarSlope ) ;
m_SuperM4th = m_SuperM / 4 ;
m_OneOverSuperN1 = - 1 / Zeps < T > ( m_SuperN1 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Hypergon , prefix + " x_hypergon " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonN , prefix + " x_hypergon_n " , 4 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonR , prefix + " x_hypergon_r " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Star , prefix + " x_star " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarN , prefix + " x_star_n " , 5 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarSlope , prefix + " x_star_slope " , 2 , eParamType : : REAL , EPS , T ( M_PI_2 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Lituus , prefix + " x_lituus " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_LituusA , prefix + " x_lituus_a " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Super , prefix + " x_super " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperM , prefix + " x_super_m " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN1 , prefix + " x_super_n1 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN2 , prefix + " x_super_n2 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN3 , prefix + " x_super_n3 " , 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_InvLituusA , prefix + " x_inv_lituus_a " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_TanStarSlope , prefix + " x_tan_star_slope " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HypergonD , prefix + " x_hypergon_d " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SuperM4th , prefix + " x_super_m_4th " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_OneOverSuperN1 , prefix + " x_one_over_super_n1 " ) ) ;
}
private :
T m_Hypergon ;
T m_HypergonN ;
T m_HypergonR ;
T m_Star ;
T m_StarN ;
T m_StarSlope ;
T m_Lituus ;
T m_LituusA ;
T m_Super ;
T m_SuperM ;
T m_SuperN1 ;
T m_SuperN2 ;
T m_SuperN3 ;
T m_InvLituusA ; //Precalc
T m_TanStarSlope ;
T m_HypergonD ;
T m_SuperM4th ;
T m_OneOverSuperN1 ;
} ;
template < typename T >
class YVariation : public ParametricVariation < T >
{
public :
YVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " y " , eVariationId : : VAR_Y , weight , true , true , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( YVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T a = helper . m_PrecalcAtanyx ;
T r ;
T s , c ;
T total = 0 ;
T temp1 , temp2 , temp4 ;
if ( m_Hypergon ! = 0 )
{
temp1 = fmod ( std : : abs ( a ) , M_2PI / m_HypergonN ) - T ( M_PI ) / m_HypergonN ;
temp2 = Sqr ( std : : tan ( temp1 ) ) + 1 ;
auto hd2 = SQR ( m_HypergonD ) ;
if ( temp2 > = hd2 )
{
total + = m_Hypergon ;
}
else
{
total + = m_Hypergon * ( m_HypergonD - std : : sqrt ( hd2 - temp2 ) ) / std : : sqrt ( temp2 ) ;
}
}
if ( m_Star ! = 0 )
{
temp1 = std : : tan ( std : : abs ( fmod ( std : : abs ( a ) , M_2PI / m_StarN ) - T ( M_PI ) / m_StarN ) ) ;
total + = m_Star * std : : sqrt ( Sqr ( m_TanStarSlope ) * ( 1 + Sqr ( temp1 ) ) / Sqr ( temp1 + m_TanStarSlope ) ) ;
}
if ( m_Lituus ! = 0 )
{
total + = m_Lituus * std : : pow ( std : : abs ( a / T ( M_PI ) + 1 ) , m_InvLituusA ) ;
}
if ( m_Super ! = 0 )
{
temp4 = a * m_SuperM4th ;
sincos ( temp4 , & s , & c ) ;
total + = m_Super * std : : pow ( std : : pow ( std : : abs ( c ) , m_SuperN2 ) + std : : pow ( std : : abs ( s ) , m_SuperN3 ) , m_OneOverSuperN1 ) ;
}
r = m_Weight * Sqr ( total ) / helper . m_PrecalcSqrtSumSquares ;
sincos ( a , & s , & c ) ;
helper . Out . x = r * c ;
helper . Out . y = r * s ;
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 hypergon = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonR = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string star = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituus = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string super = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invLituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc
string tanStarSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonD = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM4th = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string oneOverSuperN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t a = precalcAtanyx; \n "
< < " \t \t real_t r; \n "
< < " \t \t real_t s, c; \n "
< < " \t \t real_t total = 0; \n "
< < " \t \t real_t temp1, temp2, temp4; \n "
< < " \n "
< < " \t \t if ( " < < hypergon < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = fmod(fabs(a), M_2PI / " < < hypergonN < < " ) - MPI / " < < hypergonN < < " ; \n "
< < " \t \t temp2 = Sqr(tan(temp1)) + 1; \n "
< < " \t \t real_t hd2 = SQR( " < < hypergonD < < " ); \n "
< < " \n "
< < " \t \t if (temp2 >= hd2) \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " * ( " < < hypergonD < < " - sqrt(hd2 - temp2)) / sqrt(temp2); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < star < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = tan(fabs(fmod(fabs(a), M_2PI / " < < starN < < " ) - MPI / " < < starN < < " )); \n "
< < " \t \t total += " < < star < < " * sqrt(Sqr( " < < tanStarSlope < < " ) * fma(temp1, temp1, (real_t)(1.0)) / Sqr(temp1 + " < < tanStarSlope < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < lituus < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t total += " < < lituus < < " * pow(fabs(a / MPI + 1), " < < invLituusA < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < super < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp4 = a * " < < superM4th < < " ; \n "
< < " \t \t s = sincos(temp4, &c); \n "
< < " \t \t total += " < < super < < " * pow(pow(fabs(c), " < < superN2 < < " ) + pow(fabs(s), " < < superN3 < < " ), " < < oneOverSuperN1 < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t r = " < < weight < < " * Sqr(total) / precalcSqrtSumSquares; \n "
< < " \t \t s = sincos(a, &c); \n "
< < " \t \t vOut.x = r * c; \n "
< < " \t \t vOut.y = r * s; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " } ;
}
virtual void Precalc ( ) override
{
m_HypergonD = std : : sqrt ( 1 + SQR ( m_HypergonR ) ) ;
m_InvLituusA = - m_LituusA ;
if ( IsClose ( m_StarSlope , T ( M_PI_2 ) ) )
m_TanStarSlope = std : : tan ( m_StarSlope - T ( 0.05 ) ) ; //Original did not do this, but it makes no sense to take tan(pi/2) because it's undefined.
else
m_TanStarSlope = std : : tan ( m_StarSlope ) ;
m_SuperM4th = m_SuperM / 4 ;
m_OneOverSuperN1 = - 1 / Zeps < T > ( m_SuperN1 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Hypergon , prefix + " y_hypergon " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonN , prefix + " y_hypergon_n " , 4 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonR , prefix + " y_hypergon_r " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Star , prefix + " y_star " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarN , prefix + " y_star_n " , 5 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarSlope , prefix + " y_star_slope " , 2 , eParamType : : REAL , EPS , T ( M_PI_2 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Lituus , prefix + " y_lituus " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_LituusA , prefix + " y_lituus_a " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Super , prefix + " y_super " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperM , prefix + " y_super_m " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN1 , prefix + " y_super_n1 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN2 , prefix + " y_super_n2 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN3 , prefix + " y_super_n3 " , 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_InvLituusA , prefix + " y_inv_lituus_a " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_TanStarSlope , prefix + " y_tan_star_slope " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HypergonD , prefix + " y_hypergon_d " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SuperM4th , prefix + " y_super_m_4th " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_OneOverSuperN1 , prefix + " y_one_over_super_n1 " ) ) ;
}
private :
T m_Hypergon ;
T m_HypergonN ;
T m_HypergonR ;
T m_Star ;
T m_StarN ;
T m_StarSlope ;
T m_Lituus ;
T m_LituusA ;
T m_Super ;
T m_SuperM ;
T m_SuperN1 ;
T m_SuperN2 ;
T m_SuperN3 ;
T m_InvLituusA ; //Precalc
T m_TanStarSlope ;
T m_HypergonD ;
T m_SuperM4th ;
T m_OneOverSuperN1 ;
} ;
template < typename T >
class ZVariation : public ParametricVariation < T >
{
public :
ZVariation ( T weight = 1.0 ) : ParametricVariation < T > ( " z " , eVariationId : : VAR_Z , weight , true , true , false , false , true )
{
Init ( ) ;
}
PARVARCOPY ( ZVariation )
virtual void Func ( IteratorHelper < T > & helper , Point < T > & outPoint , QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand ) override
{
T a = helper . m_PrecalcAtanyx ;
T r ;
T s , c ;
T total = 0 ;
T temp1 , temp2 , temp4 ;
if ( m_Hypergon ! = 0 )
{
temp1 = fmod ( std : : abs ( a ) , M_2PI / m_HypergonN ) - T ( M_PI ) / m_HypergonN ;
temp2 = Sqr ( std : : tan ( temp1 ) ) + 1 ;
auto hd2 = SQR ( m_HypergonD ) ;
if ( temp2 > = hd2 )
{
total + = m_Hypergon ;
}
else
{
total + = m_Hypergon * ( m_HypergonD - std : : sqrt ( hd2 - temp2 ) ) / std : : sqrt ( temp2 ) ;
}
}
if ( m_Star ! = 0 )
{
temp1 = std : : tan ( std : : abs ( fmod ( std : : abs ( a ) , M_2PI / m_StarN ) - T ( M_PI ) / m_StarN ) ) ;
total + = m_Star * std : : sqrt ( Sqr ( m_TanStarSlope ) * ( 1 + Sqr ( temp1 ) ) / Sqr ( temp1 + m_TanStarSlope ) ) ;
}
if ( m_Lituus ! = 0 )
{
total + = m_Lituus * std : : pow ( std : : abs ( a / T ( M_PI ) + 1 ) , m_InvLituusA ) ;
}
if ( m_Super ! = 0 )
{
temp4 = a * m_SuperM4th ;
sincos ( temp4 , & s , & c ) ;
total + = m_Super * std : : pow ( std : : pow ( std : : abs ( c ) , m_SuperN2 ) + std : : pow ( std : : abs ( s ) , m_SuperN3 ) , m_OneOverSuperN1 ) ;
}
r = m_Weight * ( helper . m_PrecalcSqrtSumSquares + total ) ;
sincos ( a , & s , & c ) ;
helper . Out . x = r * c ;
helper . Out . y = r * s ;
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 hypergon = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonR = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string star = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starN = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string starSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituus = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string lituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string super = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN2 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superN3 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string invLituusA = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ; //Precalc
string tanStarSlope = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string hypergonD = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string superM4th = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
string oneOverSuperN1 = " parVars[ " + ToUpper ( m_Params [ i + + ] . Name ( ) ) + index ;
ss < < " \t { \n "
< < " \t \t real_t a = precalcAtanyx; \n "
< < " \t \t real_t a90 = atan2(vIn.x, -vIn.y); \n "
< < " \t \t real_t r; \n "
< < " \t \t real_t s, c; \n "
< < " \t \t real_t total = 0; \n "
< < " \t \t real_t temp1, temp2, temp4; \n "
< < " \n "
< < " \t \t if ( " < < hypergon < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = fmod(fabs(a), M_2PI / " < < hypergonN < < " ) - MPI / " < < hypergonN < < " ; \n "
< < " \t \t temp2 = Sqr(tan(temp1)) + 1; \n "
< < " \t \t real_t hd2 = SQR( " < < hypergonD < < " ); \n "
< < " \n "
< < " \t \t if (temp2 >= hd2) \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " ; \n "
< < " \t \t } \n "
< < " \t \t else \n "
< < " \t \t { \n "
< < " \t \t total += " < < hypergon < < " * ( " < < hypergonD < < " - sqrt(hd2 - temp2)) / sqrt(temp2); \n "
< < " \t \t } \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < star < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp1 = tan(fabs(fmod(fabs(a), M_2PI / " < < starN < < " ) - MPI / " < < starN < < " )); \n "
< < " \t \t total += " < < star < < " * sqrt(Sqr( " < < tanStarSlope < < " ) * fma(temp1, temp1, (real_t)(1.0)) / Sqr(temp1 + " < < tanStarSlope < < " )); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < lituus < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t total += " < < lituus < < " * pow(fabs(a / MPI + 1), " < < invLituusA < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t if ( " < < super < < " != 0) \n "
< < " \t \t { \n "
< < " \t \t temp4 = a * " < < superM4th < < " ; \n "
< < " \t \t s = sincos(temp4, &c); \n "
< < " \t \t total += " < < super < < " * pow(pow(fabs(c), " < < superN2 < < " ) + pow(fabs(s), " < < superN3 < < " ), " < < oneOverSuperN1 < < " ); \n "
< < " \t \t } \n "
< < " \n "
< < " \t \t r = " < < weight < < " * (precalcSqrtSumSquares + total); \n "
< < " \t \t s = sincos(a, &c); \n "
< < " \t \t vOut.x = r * c; \n "
< < " \t \t vOut.y = r * s; \n "
< < " \t \t vOut.z = " < < DefaultZCl ( )
< < " \t } \n " ;
return ss . str ( ) ;
}
virtual vector < string > OpenCLGlobalFuncNames ( ) const override
{
return vector < string > { " Sqr " } ;
}
virtual void Precalc ( ) override
{
m_HypergonD = std : : sqrt ( 1 + SQR ( m_HypergonR ) ) ;
m_InvLituusA = - m_LituusA ;
if ( IsClose ( m_StarSlope , T ( M_PI_2 ) ) )
m_TanStarSlope = std : : tan ( m_StarSlope - T ( 0.05 ) ) ; //Original did not do this, but it makes no sense to take tan(pi/2) because it's undefined.
else
m_TanStarSlope = std : : tan ( m_StarSlope ) ;
m_SuperM4th = m_SuperM / 4 ;
m_OneOverSuperN1 = - 1 / Zeps < T > ( m_SuperN1 ) ;
}
protected :
void Init ( )
{
string prefix = Prefix ( ) ;
m_Params . clear ( ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Hypergon , prefix + " z_hypergon " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonN , prefix + " z_hypergon_n " , 4 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_HypergonR , prefix + " z_hypergon_r " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Star , prefix + " z_star " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarN , prefix + " z_star_n " , 5 , eParamType : : INTEGER , 3 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_StarSlope , prefix + " z_star_slope " , 2 , eParamType : : REAL , EPS , T ( M_PI_2 ) ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Lituus , prefix + " z_lituus " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_LituusA , prefix + " z_lituus_a " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_Super , prefix + " z_super " ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperM , prefix + " z_super_m " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN1 , prefix + " z_super_n1 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN2 , prefix + " z_super_n2 " , 1 ) ) ;
m_Params . push_back ( ParamWithName < T > ( & m_SuperN3 , prefix + " z_super_n3 " , 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_InvLituusA , prefix + " z_inv_lituus_a " ) ) ; //Precalc.
2023-04-25 19:59:54 -04:00
m_Params . push_back ( ParamWithName < T > ( true , & m_TanStarSlope , prefix + " z_tan_star_slope " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_HypergonD , prefix + " z_hypergon_d " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_SuperM4th , prefix + " z_super_m_4th " ) ) ;
m_Params . push_back ( ParamWithName < T > ( true , & m_OneOverSuperN1 , prefix + " z_one_over_super_n1 " ) ) ;
}
private :
T m_Hypergon ;
T m_HypergonN ;
T m_HypergonR ;
T m_Star ;
T m_StarN ;
T m_StarSlope ;
T m_Lituus ;
T m_LituusA ;
T m_Super ;
T m_SuperM ;
T m_SuperN1 ;
T m_SuperN2 ;
T m_SuperN3 ;
T m_InvLituusA ; //Precalc
T m_TanStarSlope ;
T m_HypergonD ;
T m_SuperM4th ;
T m_OneOverSuperN1 ;
} ;
MAKEPREPOSTPARVAR ( Hexes , hexes , HEXES )
MAKEPREPOSTPARVAR ( Nblur , nBlur , NBLUR )
MAKEPREPOSTPARVAR ( Octapol , octapol , OCTAPOL )
MAKEPREPOSTPARVAR ( Crob , crob , CROB )
MAKEPREPOSTPARVAR ( BubbleT3D , bubbleT3D , BUBBLET3D )
MAKEPREPOSTPARVAR ( Synth , synth , SYNTH )
MAKEPREPOSTPARVAR ( Crackle , crackle , CRACKLE )
MAKEPREPOSTPARVAR ( Crackle2 , crackle2 , CRACKLE2 )
MAKEPREPOSTVAR ( Erf , erf , ERF )
MAKEPREPOSTVAR ( Xerf , xerf , XERF )
MAKEPREPOSTPARVAR ( W , w , W )
MAKEPREPOSTPARVAR ( X , x , X )
MAKEPREPOSTPARVAR ( Y , y , Y )
MAKEPREPOSTPARVAR ( Z , z , Z )
}