mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 05:00:06 -05:00
--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.
This commit is contained in:
parent
1a1cb8b0f2
commit
745f06d29d
@ -1,7 +1,7 @@
|
||||
<Project Sdk="WixToolset.Sdk/4.0.0">
|
||||
<PropertyGroup>
|
||||
<ProductVersion>3.7</ProductVersion>
|
||||
<OutputName>Fractorium_23.23.8.1</OutputName>
|
||||
<OutputName>Fractorium_23.23.8.100</OutputName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>$(SolutionDir)..\..\..\Bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
|
||||
<?define ProductVersion="23.23.8.1" ?>
|
||||
<?define ProductVersion="23.23.8.100" ?>
|
||||
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
|
||||
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
|
||||
<?define Manufacturer="Fractorium"?>
|
||||
@ -12,7 +12,7 @@
|
||||
<!--
|
||||
Change this for every release.
|
||||
-->
|
||||
<?define ProductCode="{533C4A1B-B52A-4843-8A5A-C7461E0B05EF}"?>
|
||||
<?define ProductCode="{03DF885D-6E38-4185-8C2F-AA95EEAC6CB9}"?>
|
||||
|
||||
<Package Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)" InstallerVersion="400" Scope="perMachine" ProductCode="$(var.ProductCode)">
|
||||
<SummaryInformation Keywords="Installer" Description="$(var.Manufacturer)" Manufacturer="$(var.Manufacturer)" />
|
||||
|
Binary file not shown.
@ -49,8 +49,8 @@
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 23, 23, 8, 1
|
||||
PRODUCTVERSION 23, 23, 8, 1
|
||||
FILEVERSION 23, 23, 8, 100
|
||||
PRODUCTVERSION 23, 23, 8, 100
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
|
||||
VALUE "FileVersion", "23, 23, 8, 1"
|
||||
VALUE "FileVersion", "23, 23, 8, 100"
|
||||
VALUE "InternalName", "EmberAnimate.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberAnimate.exe"
|
||||
VALUE "ProductName", "Ember Animate"
|
||||
VALUE "ProductVersion", "23, 23, 8, 1"
|
||||
VALUE "ProductVersion", "23, 23, 8, 100"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Binary file not shown.
@ -49,8 +49,8 @@
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 23, 23, 8, 1
|
||||
PRODUCTVERSION 23, 23, 8, 1
|
||||
FILEVERSION 23, 23, 8, 100
|
||||
PRODUCTVERSION 23, 23, 8, 100
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Manipulates fractal flame parameter files"
|
||||
VALUE "FileVersion", "23, 23, 8, 1"
|
||||
VALUE "FileVersion", "23, 23, 8, 100"
|
||||
VALUE "InternalName", "EmberGenome.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberGenome.exe"
|
||||
VALUE "ProductName", "Ember Genome"
|
||||
VALUE "ProductVersion", "23, 23, 8, 1"
|
||||
VALUE "ProductVersion", "23, 23, 8, 100"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -49,8 +49,8 @@
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 23, 23, 8, 1
|
||||
PRODUCTVERSION 23, 23, 8, 1
|
||||
FILEVERSION 23, 23, 8, 100
|
||||
PRODUCTVERSION 23, 23, 8, 100
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Renders fractal flames as single images"
|
||||
VALUE "FileVersion", "23, 23, 8, 1"
|
||||
VALUE "FileVersion", "23, 23, 8, 100"
|
||||
VALUE "InternalName", "EmberRender.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberRender.exe"
|
||||
VALUE "ProductName", "Ember Render"
|
||||
VALUE "ProductVersion", "23, 23, 8, 1"
|
||||
VALUE "ProductVersion", "23, 23, 8, 100"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28010.2036
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.7.34202.233
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ember", "Ember.vcxproj", "{2BDB7A54-BB1A-476B-A6E5-F81E90AD4E67}"
|
||||
EndProject
|
||||
@ -17,7 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmberGenome", "EmberGenome.
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmberCL", "EmberCL.vcxproj", "{F6A9102C-69A9-48FB-BC4B-49E49AF43236}"
|
||||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "FractoriumInstaller", "..\Installer\FractoriumInstaller.wixproj", "{C8096C47-E358-438C-A520-146D46B0637D}"
|
||||
Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "FractoriumInstaller", "..\Installer\FractoriumInstaller.wixproj", "{C8096C47-E358-438C-A520-146D46B0637D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F6A9102C-69A9-48FB-BC4B-49E49AF43236} = {F6A9102C-69A9-48FB-BC4B-49E49AF43236}
|
||||
{4A191F4C-03AC-4F1B-AFFD-F5483ECEBD29} = {4A191F4C-03AC-4F1B-AFFD-F5483ECEBD29}
|
||||
|
@ -1,4 +1,4 @@
|
||||
23.23.8.1 8/6/2023
|
||||
23.23.8.100 8/6/2023
|
||||
|
||||
--User changes
|
||||
-Add Clear Sequence button to the Sequence Panel.
|
||||
|
@ -497,6 +497,7 @@ uint Timing::m_ProcessorCount;
|
||||
EXPORTPREPOSTREGVAR(Inkdrop, T) \
|
||||
EXPORTPREPOSTREGVAR(HexModulus, T) \
|
||||
EXPORTPREPOSTREGVAR(Vignette, T) \
|
||||
EXPORTPREPOSTREGVAR(Circle_Rand, T) \
|
||||
template EMBER_API class VariationList<T>; \
|
||||
template EMBER_API class SpatialFilter<T>; \
|
||||
template EMBER_API class GaussianFilter<T>; \
|
||||
|
@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
|
||||
|
||||
namespace EmberNs
|
||||
{
|
||||
#define EMBER_VERSION "23.23.8.1"
|
||||
#define EMBER_VERSION "23.23.8.100"
|
||||
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h
|
||||
#define EPS6 T(1e-6)
|
||||
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
|
||||
|
@ -96,6 +96,7 @@ enum class eVariationId : glm::uint
|
||||
VAR_CIRCLERAND,
|
||||
VAR_CIRCLESPLIT,
|
||||
VAR_CIRCLETRANS1,
|
||||
VAR_CIRCLE_RAND,
|
||||
VAR_CIRCLIZE ,
|
||||
VAR_CIRCLIZE2 ,
|
||||
VAR_CIRCUS,
|
||||
@ -514,6 +515,7 @@ enum class eVariationId : glm::uint
|
||||
VAR_PRE_CIRCLERAND,
|
||||
VAR_PRE_CIRCLESPLIT,
|
||||
VAR_PRE_CIRCLETRANS1,
|
||||
VAR_PRE_CIRCLE_RAND,
|
||||
VAR_PRE_CIRCLIZE,
|
||||
VAR_PRE_CIRCLIZE2,
|
||||
VAR_PRE_CIRCUS,
|
||||
@ -931,6 +933,7 @@ enum class eVariationId : glm::uint
|
||||
VAR_POST_CIRCLERAND,
|
||||
VAR_POST_CIRCLESPLIT,
|
||||
VAR_POST_CIRCLETRANS1,
|
||||
VAR_POST_CIRCLE_RAND,
|
||||
VAR_POST_CIRCLIZE,
|
||||
VAR_POST_CIRCLIZE2,
|
||||
VAR_POST_CIRCUS,
|
||||
@ -2213,14 +2216,12 @@ public:
|
||||
if (!_stricmp(param.Name().c_str(), name))
|
||||
{
|
||||
param.Set(val);
|
||||
this->Precalc();
|
||||
b = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (b)
|
||||
this->Precalc();
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@ -2235,10 +2236,11 @@ public:
|
||||
bool b = false;
|
||||
|
||||
if (index < m_Params.size())
|
||||
{
|
||||
m_Params[index].Set(val);
|
||||
|
||||
if (b)
|
||||
this->Precalc();
|
||||
b = true;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
@ -2268,8 +2270,6 @@ public:
|
||||
void Clear()
|
||||
{
|
||||
for (auto& param : m_Params) *(param.Param()) = 0;
|
||||
|
||||
this->Precalc();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -330,6 +330,7 @@ VariationList<T>::VariationList()
|
||||
ADDPREPOSTREGVAR(CircleLinear)
|
||||
ADDPREPOSTREGVAR(CircleRand)
|
||||
ADDPREPOSTREGVAR(CircleTrans1)
|
||||
ADDPREPOSTREGVAR(Circle_Rand)
|
||||
ADDPREPOSTREGVAR(Cubic3D)
|
||||
ADDPREPOSTREGVAR(CubicLattice3D)
|
||||
ADDPREPOSTREGVAR(Foci3D)
|
||||
|
@ -1691,7 +1691,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string vSin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
string vfCos = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -1729,14 +1729,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "perspective_angle"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "perspective_angle"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "perspective_dist"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Vsin, prefix + "perspective_vsin"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_VfCos, prefix + "perspective_vfcos"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Angle;//Params.
|
||||
T m_Angle;
|
||||
T m_Dist;
|
||||
T m_Vsin;//Precalc.
|
||||
T m_VfCos;
|
||||
@ -1808,7 +1808,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -1842,14 +1842,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "julian_dist", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "julian_dist", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "julian_power", 1, eParamType::INTEGER_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Rn, prefix + "julian_rn"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Cn, prefix + "julian_cn"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Dist;//Params.
|
||||
T m_Dist;
|
||||
T m_Power;
|
||||
T m_Rn;//Precalc.
|
||||
T m_Cn;
|
||||
@ -1900,7 +1900,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string rn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
string cn = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -1954,14 +1954,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "juliascope_dist", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "juliascope_dist", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "juliascope_power", 1, eParamType::REAL_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Rn, prefix + "juliascope_rn"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Cn, prefix + "juliascope_cn"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Dist;//Params.
|
||||
T m_Dist;
|
||||
T m_Power;
|
||||
T m_Rn;//Precalc.
|
||||
T m_Cn;
|
||||
@ -2113,7 +2113,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string spin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
string zoom = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
ss << "\t{\n"
|
||||
@ -2144,13 +2144,13 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "radial_blur_angle"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "radial_blur_angle"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Spin, prefix + "radial_blur_spin"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Zoom, prefix + "radial_blur_zoom"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Angle;//Params.
|
||||
T m_Angle;
|
||||
T m_Spin;//Precalc.
|
||||
T m_Zoom;
|
||||
};
|
||||
@ -2222,7 +2222,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Slices, prefix + "pie_slices", 6, eParamType::INTEGER_NONZERO, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "pie_rotation", T(0.5), eParamType::REAL_CYCLIC, 0, M_2PI));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "pie_thickness", T(0.5), eParamType::REAL, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Pi2Slices, prefix + "pie_pi2_slices"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Pi2Slices, prefix + "pie_pi2_slices"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2326,7 +2326,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "ngon_power", 3));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Circle, prefix + "ngon_circle", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Corners, prefix + "ngon_corners", 2));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CSides, prefix + "ngon_csides"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CSides, prefix + "ngon_csides"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CSidesInv, prefix + "ngon_csides_inv"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CPower, prefix + "ngon_cpower"));
|
||||
}
|
||||
@ -2986,7 +2986,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string rot = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string rot = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string twist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string sinAdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
string cosAdd = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -3037,7 +3037,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rot, prefix + "disc2_rot"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rot, prefix + "disc2_rot"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Twist, prefix + "disc2_twist"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinAdd, prefix + "disc2_sin_add"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosAdd, prefix + "disc2_cos_add"));
|
||||
@ -3045,7 +3045,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Rot;//Params.
|
||||
T m_Rot;
|
||||
T m_Twist;
|
||||
T m_SinAdd;//Precalc.
|
||||
T m_CosAdd;
|
||||
@ -3087,7 +3087,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string m = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string m = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string n1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string n2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string n3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -3131,7 +3131,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_M, prefix + "super_shape_m"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_M, prefix + "super_shape_m"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_N1, prefix + "super_shape_n1", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_N2, prefix + "super_shape_n2", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_N3, prefix + "super_shape_n3", 1));
|
||||
@ -3142,7 +3142,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_M;//Params.
|
||||
T m_M;
|
||||
T m_N1;
|
||||
T m_N2;
|
||||
T m_N3;
|
||||
@ -3493,14 +3493,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "bent2_x", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "bent2_x", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "bent2_y", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Vx, prefix + "bent2_vx"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Vy, prefix + "bent2_vy"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_X;//Params.
|
||||
T m_X;
|
||||
T m_Y;
|
||||
T m_Vx;//Precalc.
|
||||
T m_Vy;
|
||||
@ -3649,14 +3649,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Shift, prefix + "bipolar_shift"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Shift, prefix + "bipolar_shift"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_S, prefix + "bipolar_s"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_V, prefix + "bipolar_v"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_V4, prefix + "bipolar_v4"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Shift;//Params.
|
||||
T m_Shift;
|
||||
T m_S;//Precalc.
|
||||
T m_V;
|
||||
T m_V4;
|
||||
@ -4014,7 +4014,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_PowerR, prefix + "cpow_r", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_PowerR, prefix + "cpow_r", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_PowerI, prefix + "cpow_i"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "cpow_power", 1, eParamType::INTEGER_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C, prefix + "cpow_c"));//Precalc.
|
||||
@ -4023,7 +4023,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_PowerR;//Params.
|
||||
T m_PowerR;
|
||||
T m_PowerI;
|
||||
T m_Power;
|
||||
T m_C;//Precalc.
|
||||
@ -4096,7 +4096,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_XAmp, prefix + "curve_xamp"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_XAmp, prefix + "curve_xamp"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YAmp, prefix + "curve_yamp"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_XLength, prefix + "curve_xlength", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YLength, prefix + "curve_ylength", 1));
|
||||
@ -4107,7 +4107,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_XAmp;//Params.
|
||||
T m_XAmp;
|
||||
T m_YAmp;
|
||||
T m_XLength;
|
||||
T m_YLength;
|
||||
@ -4472,13 +4472,13 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Beta, prefix + "escher_beta"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Beta, prefix + "escher_beta"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C, prefix + "escher_beta_c"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_D, prefix + "escher_beta_d"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Beta;//Params.
|
||||
T m_Beta;
|
||||
T m_C;//Precalc.
|
||||
T m_D;
|
||||
};
|
||||
@ -4806,14 +4806,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "modulus_x", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "modulus_x", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "modulus_y", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_XRange, prefix + "modulus_xrange"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_YRange, prefix + "modulus_yrange"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_X;//Params.
|
||||
T m_X;
|
||||
T m_Y;
|
||||
T m_XRange;//Precalc.
|
||||
T m_YRange;
|
||||
@ -4910,7 +4910,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Separation, prefix + "oscilloscope_separation", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Separation, prefix + "oscilloscope_separation", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Frequency, prefix + "oscilloscope_frequency", T(M_PI)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Amplitude, prefix + "oscilloscope_amplitude", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Damping, prefix + "oscilloscope_damping"));
|
||||
@ -4918,7 +4918,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Separation;//Params.
|
||||
T m_Separation;
|
||||
T m_Frequency;
|
||||
T m_Amplitude;
|
||||
T m_Damping;
|
||||
@ -5015,7 +5015,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Separation, prefix + "oscilloscope2_separation", 1, eParamType::REAL, 0));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Separation, prefix + "oscilloscope2_separation", 1, eParamType::REAL, 0));
|
||||
m_Params.push_back(ParamWithName<T>(&m_FrequencyX, prefix + "oscilloscope2_frequencyx", T(M_PI)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_FrequencyY, prefix + "oscilloscope2_frequencyy", T(M_PI)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Amplitude, prefix + "oscilloscope2_amplitude", 1));
|
||||
@ -5026,7 +5026,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Separation;//Params.
|
||||
T m_Separation;
|
||||
T m_FrequencyX;
|
||||
T m_FrequencyY;
|
||||
T m_Amplitude;
|
||||
@ -5391,7 +5391,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "separation_x", 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "separation_x", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_XInside, prefix + "separation_xinside"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "separation_y", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YInside, prefix + "separation_yinside"));
|
||||
@ -5400,7 +5400,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_X;//Params.
|
||||
T m_X;
|
||||
T m_XInside;
|
||||
T m_Y;
|
||||
T m_YInside;
|
||||
@ -5481,14 +5481,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_XSize, prefix + "split_xsize", T(0.5)));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_XSize, prefix + "split_xsize", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YSize, prefix + "split_ysize", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_XAng, prefix + "split_xang"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_YAng, prefix + "split_yang"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_XSize;//Params.
|
||||
T m_XSize;
|
||||
T m_YSize;
|
||||
T m_XAng;//Precalc.
|
||||
T m_YAng;
|
||||
@ -5701,7 +5701,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "wedge_angle", T(M_PI_2)));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "wedge_angle", T(M_PI_2)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Hole, prefix + "wedge_hole"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Count, prefix + "wedge_count", 2, eParamType::INTEGER, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Swirl, prefix + "wedge_swirl"));
|
||||
@ -5709,7 +5709,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Angle;//Params.
|
||||
T m_Angle;
|
||||
T m_Hole;
|
||||
T m_Count;
|
||||
T m_Swirl;
|
||||
@ -5749,7 +5749,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string count = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -5790,7 +5790,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "wedge_julia_angle"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "wedge_julia_angle"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Count, prefix + "wedge_julia_count", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "wedge_julia_power", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "wedge_julia_dist"));
|
||||
@ -5800,7 +5800,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Angle;//Params.
|
||||
T m_Angle;
|
||||
T m_Count;
|
||||
T m_Power;
|
||||
T m_Dist;
|
||||
@ -5890,7 +5890,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Count, prefix + "wedge_sph_count", 2, eParamType::INTEGER, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Hole, prefix + "wedge_sph_hole"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Swirl, prefix + "wedge_sph_swirl"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C12Pi, prefix + "wedge_sph_c1_2pi"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C12Pi, prefix + "wedge_sph_c1_2pi"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CompFac, prefix + "wedge_sph_comp_fac"));
|
||||
}
|
||||
|
||||
@ -7342,12 +7342,12 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Spread, prefix + "flux_spread"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Spread, prefix + "flux_spread"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Spr, prefix + "flux_spr"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Spread;//Params.
|
||||
T m_Spread;
|
||||
T m_Spr;//Precalc.
|
||||
};
|
||||
|
||||
|
@ -116,7 +116,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_N, prefix + "epispiral_n", 6));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "epispiral_thickness"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Holes, prefix + "epispiral_holes", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_ThicknessWeight, prefix + "epispiral_thickness_weight")); //Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_ThicknessWeight, prefix + "epispiral_thickness_weight"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HolesWeight, prefix + "epispiral_holes_weight"));
|
||||
}
|
||||
|
||||
@ -5862,7 +5862,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Weight01, prefix + "bisplit_weight01"));//Precalc only.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Weight01, prefix + "bisplit_weight01"));//Precalcs only, no params.
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -584,7 +584,7 @@ private:
|
||||
*y = r * sinPhi + m_Y1;
|
||||
}
|
||||
|
||||
T m_Radius;//Params.
|
||||
T m_Radius;
|
||||
T m_Radius1;
|
||||
T m_Phi1;
|
||||
T m_Thickness;
|
||||
@ -742,7 +742,7 @@ private:
|
||||
*y = r * sinPhi;
|
||||
}
|
||||
|
||||
T m_Radius;//Params.
|
||||
T m_Radius;
|
||||
T m_Thickness;
|
||||
T m_Contrast;
|
||||
T m_Pow;
|
||||
@ -907,7 +907,7 @@ private:
|
||||
*y = r * sinPhi;
|
||||
}
|
||||
|
||||
T m_Radius;//Params.
|
||||
T m_Radius;
|
||||
T m_Thickness;
|
||||
T m_Thickness2;
|
||||
T m_Contrast;
|
||||
@ -1014,7 +1014,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Radius;//Params.
|
||||
T m_Radius;
|
||||
T m_Contrast;
|
||||
T m_Pow;
|
||||
T m_X;
|
||||
@ -1123,7 +1123,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Radius;//Params.
|
||||
T m_Radius;
|
||||
T m_Thickness;
|
||||
T m_Contrast;
|
||||
T m_Pow;
|
||||
|
@ -1682,7 +1682,7 @@ private:
|
||||
return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) * am;
|
||||
}
|
||||
|
||||
T m_K;//Params.
|
||||
T m_K;
|
||||
T m_Step;
|
||||
T m_Num;
|
||||
T m_XSeed;
|
||||
@ -1804,7 +1804,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_XThickness, prefix + "waffle_xthickness", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YThickness, prefix + "waffle_ythickness", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "waffle_rotation"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinR, prefix + "waffle_sinr"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinR, prefix + "waffle_sinr"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosR, prefix + "waffle_cosr"));
|
||||
}
|
||||
|
||||
@ -2284,7 +2284,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "circlecrop_y"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_ScatterArea, prefix + "circlecrop_scatter_area"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Zero, prefix + "circlecrop_zero", 1, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ca, prefix + "circlecrop_ca"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ca, prefix + "circlecrop_ca"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2392,7 +2392,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Inner, prefix + "circlecrop2_inner", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Outer, prefix + "circlecrop2_outer", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Zero, prefix + "circlecrop2_zero", 1, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_In, prefix + "circlecrop2_in"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_In, prefix + "circlecrop2_in"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Out, prefix + "circlecrop2_out"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_OutWeight, prefix + "circlecrop2_out_weight"));
|
||||
}
|
||||
@ -2491,7 +2491,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Dist;//Params.
|
||||
T m_Dist;
|
||||
T m_Power;
|
||||
T m_A;
|
||||
T m_B;
|
||||
@ -3062,7 +3062,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Sx, prefix + "curl_sp_sx"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Sy, prefix + "curl_sp_sy"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dc, prefix + "curl_sp_dc"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C2x2, prefix + "curl_sp_c2_x2"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C2x2, prefix + "curl_sp_c2_x2"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_DcAdjust, prefix + "curl_sp_dc_adjust"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_PowerInv, prefix + "curl_sp_power_inv"));
|
||||
}
|
||||
@ -3191,7 +3191,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rperiod, prefix + "heat_r_period", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rphase, prefix + "heat_r_phase"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Ramp, prefix + "heat_r_amp"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_At, prefix + "heat_at"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_At, prefix + "heat_at"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Bt, prefix + "heat_bt"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ct, prefix + "heat_ct"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ap, prefix + "heat_ap"));
|
||||
@ -4932,7 +4932,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_CenterY, prefix + "gdoffs_center_y"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Gamma, prefix + "gdoffs_gamma", 1, eParamType::INTEGER, 1, 6));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Square, prefix + "gdoffs_square", 0, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Dx, prefix + "gdoffs_dx"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Dx, prefix + "gdoffs_dx"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ax, prefix + "gdoffs_ax"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Cx, prefix + "gdoffs_cx"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Dy, prefix + "gdoffs_dyd"));
|
||||
@ -4948,7 +4948,7 @@ private:
|
||||
static inline T GdoffsFosc(T p, T a) { return GdoffsFscl(-1 * std::cos(p * a * M_2PI)); }
|
||||
static inline T GdoffsFlip(T a, T b, T c) { return (c * (b - a) + a); }
|
||||
|
||||
T m_DeltaX;//Params.
|
||||
T m_DeltaX;
|
||||
T m_DeltaY;
|
||||
T m_AreaX;
|
||||
T m_AreaY;
|
||||
@ -5245,7 +5245,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_D1, prefix + "trade_d1", 1, eParamType::REAL, 0, TMAX));
|
||||
m_Params.push_back(ParamWithName<T>(&m_R2, prefix + "trade_r2", 1, eParamType::REAL, EPS, TMAX));
|
||||
m_Params.push_back(ParamWithName<T>(&m_D2, prefix + "trade_d2", 1, eParamType::REAL, 0, TMAX));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C1, prefix + "trade_c1"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C1, prefix + "trade_c1"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_C2, prefix + "trade_c2"));
|
||||
}
|
||||
|
||||
@ -5326,7 +5326,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Re, prefix + "Juliac_re", 2));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Im, prefix + "Juliac_im", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dist, prefix + "Juliac_dist", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HalfDist, prefix + "Juliac_half_dist"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HalfDist, prefix + "Juliac_half_dist"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_ReInv, prefix + "Juliac_re_inv"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_OneOverReInv, prefix + "Juliac_one_over_re_inv"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Im100, prefix + "Juliac_im100"));
|
||||
|
@ -819,7 +819,7 @@ protected:
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Xpand, prefix + "cubic3D_xpand", T(0.25)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Style, prefix + "cubic3D_style"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Fill, prefix + "cubic3D_fill")); //Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Fill, prefix + "cubic3D_fill"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Smooth, prefix + "cubic3D_smooth"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SmoothStyle, prefix + "cubic3D_smooth_style"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SmoothFill, prefix + "cubic3D_smooth_fill"));
|
||||
@ -2043,7 +2043,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "popcorn2_3D_y", T(0.1)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Z, prefix + "popcorn2_3D_z", T(0.1)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_C, prefix + "popcorn2_3D_c", 3));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinTanC, prefix + "popcorn2_3D_sintanc"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinTanC, prefix + "popcorn2_3D_sintanc"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HalfWeight, prefix + "popcorn2_3D_half_weight"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Vv, prefix + "popcorn2_3D_vv"));
|
||||
}
|
||||
@ -2225,7 +2225,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_XWidth, prefix + "shredlin_xwidth", T(0.5), eParamType::REAL, -1, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YDistance, prefix + "shredlin_ydistance", 1, eParamType::REAL_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(&m_YWidth, prefix + "shredlin_ywidth", T(0.5), eParamType::REAL, -1, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Xw, prefix + "shredlin_xw"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Xw, prefix + "shredlin_xw"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Yw, prefix + "shredlin_yw"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_1mX, prefix + "shredlin_1mx"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_1mY, prefix + "shredlin_1my"));
|
||||
@ -2585,7 +2585,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Invert, prefix + "falloff_invert", 0, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Type, prefix + "falloff_type", 0, eParamType::INTEGER, 0, 2));
|
||||
m_Params.push_back(ParamWithName<T>(&m_BoxPow, prefix + "falloff_boxpow", 2, eParamType::INTEGER, 2, 32));//Original defaulted this to 0 which directly contradicts the specified range of 2-32.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InternalScatter, prefix + "falloff_internal_scatter"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InternalScatter, prefix + "falloff_internal_scatter"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3625,7 +3625,7 @@ public:
|
||||
//Creating Z factors relative to the planes. These will be added, whereas x and y will be assigned.
|
||||
//Original does += z *, so using z on the right side of = is intentional.
|
||||
if (m_MajPlane == 2)
|
||||
//Boost is the separation distance between the two planes.
|
||||
//Boost is the separation distance between the two planes.
|
||||
helper.Out.z = helper.In.z * T(0.5) * m_ZLift + (posNeg * m_Boost);
|
||||
else
|
||||
helper.Out.z = helper.In.z * T(0.5) * m_ZLift;
|
||||
|
@ -1752,7 +1752,7 @@ protected:
|
||||
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));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_XInterval, prefix + "crob_xinterval"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_XInterval, prefix + "crob_xinterval"));//Precalc.
|
||||
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"));
|
||||
@ -3889,7 +3889,7 @@ protected:
|
||||
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"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HalfCellSize, prefix + "crackle_half_cellsize"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_HalfCellSize, prefix + "crackle_half_cellsize"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &(m_C[0][0].x), prefix + "crackle_cache", sizeof(m_C)));
|
||||
}
|
||||
|
||||
@ -4028,7 +4028,7 @@ protected:
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Cellsize, prefix + "crackle2_cellsize", 1, eParamType::REAL, T(0.0001)));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_OneOverCellsize, prefix + "crackle2_one_over_cellsize"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_OneOverCellsize, prefix + "crackle2_one_over_cellsize"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
@ -4876,7 +4876,7 @@ protected:
|
||||
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));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "w_inv_lituus_a"));//Precalc
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "w_inv_lituus_a"));//Precalc.
|
||||
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"));
|
||||
@ -5076,7 +5076,7 @@ protected:
|
||||
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));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "x_inv_lituus_a"));//Precalc
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "x_inv_lituus_a"));//Precalc.
|
||||
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"));
|
||||
@ -5276,7 +5276,7 @@ protected:
|
||||
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));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "y_inv_lituus_a"));//Precalc
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "y_inv_lituus_a"));//Precalc.
|
||||
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"));
|
||||
@ -5477,7 +5477,7 @@ protected:
|
||||
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));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "z_inv_lituus_a"));//Precalc
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_InvLituusA, prefix + "z_inv_lituus_a"));//Precalc.
|
||||
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"));
|
||||
|
@ -821,7 +821,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_F, prefix + "pRose3D_f", 3));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Wigsc, prefix + "pRose3D_wigsc"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "pRose3D_offset"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Cycle, prefix + "pRose3D_cycle"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Cycle, prefix + "pRose3D_cycle"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_OptDir, prefix + "pRose3D_opt_dir"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_PetalsSign, prefix + "pRose3D_petals_sign"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_NumPetals, prefix + "pRose3D_num_petals"));
|
||||
@ -954,7 +954,7 @@ protected:
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Base, prefix + "log_db_base", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_FixPeriod, prefix + "log_db_fix_period", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Denom, prefix + "log_db_denom"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Denom, prefix + "log_db_denom"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_FixPe, prefix + "log_db_fix_pe"));
|
||||
}
|
||||
private:
|
||||
@ -4486,7 +4486,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Freq2, prefix + "vibration_freq2", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Amp2, prefix + "vibration_amp2", T(0.25)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Phase2, prefix + "vibration_phase2", 0, eParamType::REAL_CYCLIC, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosDir, prefix + "vibration_cos_dir"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosDir, prefix + "vibration_cos_dir"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinDir, prefix + "vibration_sin_dir"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosTot, prefix + "vibration_cos_tot"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinTot, prefix + "vibration_sin_tot"));
|
||||
@ -4701,7 +4701,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_F2mfreq, prefix + "vibration2_fmfreq2"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_A2m , prefix + "vibration2_am2"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_A2mfreq, prefix + "vibration2_amfreq2"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosDir, prefix + "vibration2_cos_dir"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_CosDir, prefix + "vibration2_cos_dir"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinDir, prefix + "vibration2_sin_dir"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_ScaledFreq, prefix + "vibration2_scaled_freq"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_PhaseShift, prefix + "vibration2_phase_shift"));
|
||||
@ -5202,8 +5202,8 @@ public:
|
||||
T z_scaled = z * std::sqrt(rand.Frand01<T>()) * T(1.1547005383792515290182975610039);//2 / sqrt(3)
|
||||
T n = VarFuncs<T>::HashShadertoy(xfinal, yfinal, m_Seed);
|
||||
T R = m_SizeOver2 * z_scaled * std::pow(n, m_Power);
|
||||
helper.Out.x = std::cos(final_angle) * R + xfinal * m_Weight;
|
||||
helper.Out.y = std::sin(final_angle) * R + yfinal * m_Weight;
|
||||
helper.Out.x = (std::cos(final_angle) * R + xfinal) * m_Weight;
|
||||
helper.Out.y = (std::sin(final_angle) * R + yfinal) * m_Weight;
|
||||
}
|
||||
|
||||
helper.Out.z = DefaultZ(helper);
|
||||
@ -5270,7 +5270,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "hex_rand_power", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Density, prefix + "hex_rand_density", 1, eParamType::REAL, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Seed, prefix + "hex_rand_seed", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SizeOver2, prefix + "hex_rand_size_over_2"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SizeOver2, prefix + "hex_rand_size_over_2"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
@ -5884,7 +5884,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_SinYAmp, prefix + "unicorngaloshen_sin_y_amplitude", 2));
|
||||
m_Params.push_back(ParamWithName<T>(&m_SinYFreq, prefix + "unicorngaloshen_sin_y_freq", T(0.2)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Mode, prefix + "unicorngaloshen_mode", 0, eParamType::INTEGER, 0, 4));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinXFreqPi, prefix + "unicorngaloshen_sin_x_freq_pi"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinXFreqPi, prefix + "unicorngaloshen_sin_x_freq_pi"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SinYFreqPi, prefix + "unicorngaloshen_sin_y_freq_pi"));
|
||||
}
|
||||
|
||||
@ -7461,7 +7461,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Scaley, prefix + "waves23_scaley", T(0.05)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Freqx, prefix + "waves23_freqx", T(7.0)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Freqy, prefix + "waves23_freqy", T(13.0)));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Freqx12Pi, prefix + "waves23_freqx_12pi"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Freqx12Pi, prefix + "waves23_freqx_12pi"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Freqy12Pi, prefix + "waves23_freqy_12pi"));
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,124 @@ private:
|
||||
T m_WeightPrecalc;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Circle_Rand.
|
||||
/// A new version of CircleRand from Chaotica by tatasz.
|
||||
/// </summary>
|
||||
template <typename T>
|
||||
class Circle_RandVariation : public ParametricVariation<T>
|
||||
{
|
||||
public:
|
||||
Circle_RandVariation(T weight = 1.0) : ParametricVariation<T>("Circle_Rand", eVariationId::VAR_CIRCLE_RAND, weight)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
PARVARCOPY(Circle_RandVariation)
|
||||
|
||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||
{
|
||||
T a = rand.Frand01<T>() * M_2PI;
|
||||
T r = std::sqrt(rand.Frand01<T>());
|
||||
T x = 2 * (Floor(rand.Frand01<T>() * m_SideX * 2 + T(0.5)) - m_SideX);
|
||||
T y = 2 * (Floor(rand.Frand01<T>() * m_SideY * 2 + T(0.5)) - m_SideY);
|
||||
T ret;
|
||||
|
||||
if (VarFuncs<T>::HashShadertoy(y, x, m_Seed) < m_Dens)
|
||||
ret = m_Size * r * std::exp(std::log(VarFuncs<T>::HashShadertoy(x, y, m_Seed)) * m_Power);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
helper.Out.x = m_Weight * (std::cos(a) * ret + x);
|
||||
helper.Out.y = m_Weight * (std::sin(a) * ret + 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 x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string y = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string size = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string density = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string seed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string sidex = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string sidey = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t seed = " << seed << ";\n"
|
||||
<< "\t\treal_t sidex = " << sidex << ";\n"
|
||||
<< "\t\treal_t sidey = " << sidey << ";\n"
|
||||
<< "\t\treal_t a = MwcNext01(mwc) * M_2PI;\n"
|
||||
<< "\t\treal_t r = sqrt(MwcNext01(mwc));\n"
|
||||
<< "\t\treal_t x = 2 * (floor(MwcNext01(mwc) * sidex * 2 + (real_t)(0.5)) - sidex);\n"
|
||||
<< "\t\treal_t y = 2 * (floor(MwcNext01(mwc) * sidey * 2 + (real_t)(0.5)) - sidey);\n"
|
||||
<< "\n"
|
||||
<< "\t\treal_t ret;\n"
|
||||
<< "\n"
|
||||
<< "\t\tif (HashShadertoy(y, x, seed) < " << density << ")\n"
|
||||
<< "\t\t ret = " << size << " * r * exp(log(HashShadertoy(x, y, seed)) * " << power << ");\n"
|
||||
<< "\t\telse"
|
||||
<< "\t\t ret = (real_t)(0.0);"
|
||||
<< "\n"
|
||||
<< "\t\tif (ret > (real_t)(0.0))\n"
|
||||
<< "\t\t{"
|
||||
<< "\t\t vOut.x = " << weight << " * fma((real_t)(cos(a)), ret, x);\n"
|
||||
<< "\t\t vOut.y = " << weight << " * fma((real_t)(sin(a)), ret, y);\n"
|
||||
<< "\t\t}"
|
||||
<< "\n"
|
||||
<< "\t\tvOut.z = " << DefaultZCl()
|
||||
<< "\t}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual vector<string> OpenCLGlobalFuncNames() const override
|
||||
{
|
||||
return vector<string> { "Fract", "HashShadertoy" };
|
||||
}
|
||||
|
||||
virtual void Precalc() override
|
||||
{
|
||||
m_SideX = m_X * T(0.5);
|
||||
m_SideY = m_Y * T(0.5);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init()
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "Circle_Rand_X", 10));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Y, prefix + "Circle_Rand_Y", 10));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Size, prefix + "Circle_Rand_size", 1, eParamType::REAL, 0));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "Circle_Rand_power", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Dens, prefix + "Circle_Rand_density", 1, eParamType::REAL, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Seed, prefix + "Circle_Rand_seed", 1, eParamType::REAL));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SideX, prefix + "Circle_Rand_side_x"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_SideY, prefix + "Circle_Rand_side_y"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_X;
|
||||
T m_Y;
|
||||
T m_Size;
|
||||
T m_Power;
|
||||
T m_Dens;
|
||||
T m_Seed;
|
||||
T m_SideX;//Precalc.
|
||||
T m_SideY;
|
||||
};
|
||||
|
||||
MAKEPREPOSTPARVAR(Gnarly, gnarly, GNARLY)
|
||||
MAKEPREPOSTPARVAR(Inkdrop, inkdrop, INKDROP)
|
||||
MAKEPREPOSTPARVAR(HexModulus, hex_modulus, HEX_MODULUS)
|
||||
MAKEPREPOSTPARVAR(Circle_Rand, circle_rand, CIRCLE_RAND)
|
||||
}
|
@ -52,7 +52,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string centerX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string centerY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string bdcs = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
@ -104,14 +104,14 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_CenterX, prefix + "dc_bubble_centerx"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_CenterX, prefix + "dc_bubble_centerx"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_CenterY, prefix + "dc_bubble_centery"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "dc_bubble_scale", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Bdcs, prefix + "dc_bubble_bdcs"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
T m_CenterX;//Params.
|
||||
T m_CenterX;
|
||||
T m_CenterY;
|
||||
T m_Scale;
|
||||
T m_Bdcs;//Precalc.
|
||||
@ -152,7 +152,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string origin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string origin = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string h = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
ss << "\t{\n"
|
||||
<< "\t\tint x0 = (MwcNext(mwc) & 1) ? -1 : 1;\n"
|
||||
@ -180,12 +180,12 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Origin, prefix + "dc_carpet_origin"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Origin, prefix + "dc_carpet_origin"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_H, prefix + "dc_carpet_h"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Origin;//Params.
|
||||
T m_Origin;
|
||||
T m_H;//Precalc.
|
||||
};
|
||||
|
||||
@ -263,7 +263,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string cubeC1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string cubeC1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string cubeC2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string cubeC3 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string cubeC4 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -345,7 +345,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_DcCubeC1, prefix + "dc_cube_c1"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_DcCubeC1, prefix + "dc_cube_c1"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_DcCubeC2, prefix + "dc_cube_c2"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_DcCubeC3, prefix + "dc_cube_c3"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_DcCubeC4, prefix + "dc_cube_c4"));
|
||||
@ -363,7 +363,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_DcCubeC1;//Params.
|
||||
T m_DcCubeC1;
|
||||
T m_DcCubeC2;
|
||||
T m_DcCubeC3;
|
||||
T m_DcCubeC4;
|
||||
@ -429,7 +429,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string x = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
@ -484,7 +484,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "dc_cylinder_offset"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "dc_cylinder_offset"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "dc_cylinder_angle"));//Original used a prefix of dc_cyl_, which is incompatible with Ember's design.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "dc_cylinder_scale", T(0.5)));
|
||||
m_Params.push_back(ParamWithName<T>(&m_X, prefix + "dc_cylinder_x", T(0.125)));//Original used a prefix of cyl_, which is incompatible with Ember's design.
|
||||
@ -497,7 +497,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Offset;//Params.
|
||||
T m_Offset;
|
||||
T m_Angle;
|
||||
T m_Scale;
|
||||
T m_X;
|
||||
@ -730,7 +730,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string offset = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string angle = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string ldcs = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
@ -778,7 +778,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "dc_linear_offset"));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "dc_linear_offset"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Angle, prefix + "dc_linear_angle"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "dc_linear_scale", 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Ldcs, prefix + "dc_linear_ldcs"));//Precalc.
|
||||
@ -788,7 +788,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Offset;//Params.
|
||||
T m_Offset;
|
||||
T m_Angle;
|
||||
T m_Scale;
|
||||
T m_Ldcs;//Precalc.
|
||||
@ -901,7 +901,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string scatterArea = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string scatterArea = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string zeroEdges = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string a = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
ss << "\t{\n"
|
||||
@ -994,13 +994,13 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_ScatterArea, prefix + "dc_triangle_scatter_area", 0, eParamType::REAL, -1, 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_ScatterArea, prefix + "dc_triangle_scatter_area", 0, eParamType::REAL, -1, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_ZeroEdges, prefix + "dc_triangle_zero_edges", 0, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_A, prefix + "dc_triangle_a"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
T m_ScatterArea;//Params.
|
||||
T m_ScatterArea;
|
||||
T m_ZeroEdges;
|
||||
T m_A;//Precalc.
|
||||
};
|
||||
@ -1044,7 +1044,7 @@ public:
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string x0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Params.
|
||||
string x0 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string x1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string factor = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string overwrite = "parVars[" + ToUpper(m_Params[i++].Name()) + index;//Precalc.
|
||||
@ -1081,7 +1081,7 @@ protected:
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_X0, prefix + "dc_ztransl_x0", 0, eParamType::REAL, 0, 1));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_X0, prefix + "dc_ztransl_x0", 0, eParamType::REAL, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_X1, prefix + "dc_ztransl_x1", 1, eParamType::REAL, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Factor, prefix + "dc_ztransl_factor", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Overwrite, prefix + "dc_ztransl_overwrite", 1, eParamType::INTEGER, 0, 1));
|
||||
@ -1092,7 +1092,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_X0;//Params.
|
||||
T m_X0;
|
||||
T m_X1;
|
||||
T m_Factor;
|
||||
T m_Overwrite;
|
||||
@ -1426,7 +1426,7 @@ protected:
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.reserve(15);
|
||||
m_Params.push_back(ParamWithName<T>(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));//Params.
|
||||
m_Params.push_back(ParamWithName<T>(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Map, prefix + "dc_perlin_map", 0, eParamType::INTEGER, 0, 5));
|
||||
m_Params.push_back(ParamWithName<T>(&m_SelectCentre, prefix + "dc_perlin_select_centre", 0, eParamType::REAL, -1, 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_SelectRange, prefix + "dc_perlin_select_range", 1, eParamType::REAL, T(0.1), 2));
|
||||
@ -1439,11 +1439,11 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Freqs, prefix + "dc_perlin_freqs", 2));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Z, prefix + "dc_perlin_z"));
|
||||
m_Params.push_back(ParamWithName<T>(&m_SelectBailout, prefix + "dc_perlin_select_bailout", 10, eParamType::INTEGER, 2, 1000));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_NotchBottom, prefix + "dc_perlin_notch_bottom"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_NotchBottom, prefix + "dc_perlin_notch_bottom"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_NotchTop, prefix + "dc_perlin_notch_top"));
|
||||
}
|
||||
private:
|
||||
T m_Shape;//Params.
|
||||
T m_Shape;
|
||||
T m_Map;
|
||||
T m_SelectCentre;
|
||||
T m_SelectRange;
|
||||
@ -1636,7 +1636,7 @@ protected:
|
||||
m_Params.push_back(ParamWithName<T>(&m_Width, prefix + "pixel_flow_width", 200));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Seed, prefix + "pixel_flow_seed", 42, eParamType::INTEGER));
|
||||
m_Params.push_back(ParamWithName<T>(&m_EnableDC, prefix + "pixel_flow_enable_dc", 0, eParamType::INTEGER, 0, 1));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Rad, prefix + "pixel_flow_rad"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Rad, prefix + "pixel_flow_rad"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -884,7 +884,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
|
||||
xmlAttrPtr att;
|
||||
currentEmber.m_Palette.Clear();//Wipe out the current palette.
|
||||
att = emberNode->properties;//The top level element is a ember element, read the attributes of it and store them.
|
||||
auto variationsfunc = [&](const string & prefix, const char* nodename, xmlNode * node, Xform<T>& xf, std::vector<std::string>& alliterweights)
|
||||
auto variationsfunc = [&](const string& prefix, const char* nodename, xmlNode * node, Xform<T>& xf, std::vector<std::string>& alliterweights)
|
||||
{
|
||||
if (const auto transformsChildNode = GetChildNode(node, nodename))
|
||||
{
|
||||
@ -1352,7 +1352,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
|
||||
{
|
||||
if (camChildNode->type == XML_ELEMENT_NODE)
|
||||
{
|
||||
if (ParseAndAssignContent(camChildNode, "name", "rotate", currentEmber.m_Rotate)) { currentEmber.m_Rotate = NormalizeDeg180<T>(currentEmber.m_Rotate); }
|
||||
if (ParseAndAssignContent(camChildNode, "name", "rotate", currentEmber.m_Rotate)) { currentEmber.m_Rotate = NormalizeDeg360<T>(currentEmber.m_Rotate); }
|
||||
else if (ParseAndAssignContent(camChildNode, "name", "sensor_width", sensorWidth)) { }
|
||||
else if (ParseAndAssignContent(camChildNode, "name", "pos", pos))
|
||||
{
|
||||
@ -1441,7 +1441,7 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
|
||||
valv = CCX(valvalsnode->children->content);
|
||||
}
|
||||
|
||||
auto parsehsvfunc = [&](const std::string & knots, const std::string & vals, vector<v2F>& vec)
|
||||
auto parsehsvfunc = [&](const std::string& knots, const std::string& vals, vector<v2F>& vec)
|
||||
{
|
||||
istringstream kstr(knots);
|
||||
istringstream vstr(vals);
|
||||
@ -1563,7 +1563,7 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
|
||||
//First parse out simple float reads.
|
||||
if (ParseAndAssign(curAtt->name, attStr, "time", currentEmber.m_Time, ret)) {}
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "scale", currentEmber.m_PixelsPerUnit, ret)) { currentEmber.m_OrigPixPerUnit = currentEmber.m_PixelsPerUnit; }
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "rotate", currentEmber.m_Rotate, ret)) { currentEmber.m_Rotate = NormalizeDeg180<T>(currentEmber.m_Rotate); }
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "rotate", currentEmber.m_Rotate, ret)) { currentEmber.m_Rotate = NormalizeDeg360<T>(currentEmber.m_Rotate); }
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "zoom", currentEmber.m_Zoom, ret)) { ClampGteRef<T>(currentEmber.m_Zoom, 0); }
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "cam_zoom", currentEmber.m_Zoom, ret)) { ClampGteRef<T>(currentEmber.m_Zoom, 0); }//JWildfire uses cam_zoom.
|
||||
else if (ParseAndAssign(curAtt->name, attStr, "filter", currentEmber.m_SpatialFilterRadius, ret)) {}
|
||||
|
@ -496,8 +496,7 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
EmberStats stats;
|
||||
EmberImageComments comments;
|
||||
Ember<T> centerEmber;
|
||||
vector<v4F> finalImages[2];
|
||||
std::thread writeThread;
|
||||
ThreadedWriter threadedWriter(16);
|
||||
os.imbue(std::locale(""));
|
||||
|
||||
//The conditions of this loop use atomics to synchronize when running on multiple GPUs.
|
||||
@ -600,8 +599,10 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
}
|
||||
|
||||
renderer->Reset();
|
||||
auto threadIndex = threadedWriter.Increment();
|
||||
auto threadImage = threadedWriter.GetImage(opt.ThreadedWrite() ? threadIndex : 0);
|
||||
|
||||
if ((renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty())
|
||||
if ((renderer->Run(*threadImage, localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || threadImage->empty())
|
||||
{
|
||||
cout << "Error: image rendering failed, aborting.\n";
|
||||
renderer->DumpErrorReport();//Something went wrong, print errors.
|
||||
@ -644,19 +645,19 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
|
||||
//Run image writing in a thread. Although doing it this way duplicates the final output memory, it saves a lot of time
|
||||
//when running with OpenCL. Call join() to ensure the previous thread call has completed.
|
||||
Join(writeThread);
|
||||
//Join(writeThread);
|
||||
const auto threadVecIndex = finalImageIndex;//Cache before launching thread.
|
||||
|
||||
if (opt.ThreadedWrite())//Copies of all but the first parameter are passed to saveFunc(), to avoid conflicting with those values changing when starting the render for the next image.
|
||||
{
|
||||
writeThread = std::thread(saveFunc, std::ref(finalImages[threadVecIndex]), baseFilename, comments, renderer->FinalRasW(), renderer->FinalRasH(), renderer->NumChannels());
|
||||
finalImageIndex ^= 1;//Toggle the index.
|
||||
auto writeThread = std::thread(saveFunc, std::ref(*threadImage), baseFilename, comments, renderer->FinalRasW(), renderer->FinalRasH(), renderer->NumChannels());
|
||||
threadedWriter.SetThread(threadIndex, writeThread);
|
||||
}
|
||||
else
|
||||
saveFunc(finalImages[threadVecIndex], baseFilename, comments, renderer->FinalRasW(), renderer->FinalRasH(), renderer->NumChannels());//Will always use the first index, thereby not requiring more memory.
|
||||
saveFunc(*threadImage, baseFilename, comments, renderer->FinalRasW(), renderer->FinalRasH(), renderer->NumChannels());//Will always use the first index, thereby not requiring more memory.
|
||||
}
|
||||
|
||||
Join(writeThread);//One final check to make sure all writing is done before exiting this thread.
|
||||
threadedWriter.JoinAll();//One final check to make sure all writing is done before exiting this thread.
|
||||
};
|
||||
threadVec.reserve(renderers.size());
|
||||
|
||||
|
@ -928,6 +928,51 @@ static bool FileExists(const string& filename, bool notempty = true)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class ThreadedWriter
|
||||
{
|
||||
public:
|
||||
ThreadedWriter(int _size)
|
||||
{
|
||||
m_Size = _size;
|
||||
m_WriteThreads.resize(m_Size);
|
||||
m_FinalImages.resize(m_Size);
|
||||
}
|
||||
|
||||
size_t Current()
|
||||
{
|
||||
return m_CurrentIndex % m_Size;
|
||||
}
|
||||
|
||||
size_t Increment()
|
||||
{
|
||||
auto ret = ++m_CurrentIndex % m_Size;
|
||||
Join(m_WriteThreads[ret]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<v4F>* GetImage(size_t i)
|
||||
{
|
||||
return &m_FinalImages[i];
|
||||
}
|
||||
|
||||
void SetThread(size_t i, std::thread& th)
|
||||
{
|
||||
Join(m_WriteThreads[i]);
|
||||
m_WriteThreads[i] = std::move(th);
|
||||
}
|
||||
|
||||
void JoinAll()
|
||||
{
|
||||
Join(m_WriteThreads);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_Size = 0;
|
||||
size_t m_CurrentIndex = 0;
|
||||
std::vector<std::thread> m_WriteThreads;
|
||||
std::vector<vector<v4F>> m_FinalImages;
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -160,34 +160,9 @@ static bool WritePng(const char* filename, unsigned char* image, size_t width, s
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_text text[PNG_COMMENT_MAX];
|
||||
size_t i = 0;
|
||||
constexpr glm::uint16 testbe = 1;
|
||||
vector<unsigned char*> rows(height);
|
||||
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[0].key = const_cast<png_charp>("ember_version");
|
||||
text[0].text = const_cast<png_charp>(EmberVersion());
|
||||
text[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[1].key = const_cast<png_charp>("ember_nickname");
|
||||
text[1].text = const_cast<png_charp>(nick.c_str());
|
||||
text[2].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[2].key = const_cast<png_charp>("ember_url");
|
||||
text[2].text = const_cast<png_charp>(url.c_str());
|
||||
text[3].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[3].key = const_cast<png_charp>("ember_id");
|
||||
text[3].text = const_cast<png_charp>(id.c_str());
|
||||
text[4].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[4].key = const_cast<png_charp>("ember_error_rate");
|
||||
text[4].text = const_cast<png_charp>(comments.m_Badvals.c_str());
|
||||
text[5].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[5].key = const_cast<png_charp>("ember_samples");
|
||||
text[5].text = const_cast<png_charp>(comments.m_NumIters.c_str());
|
||||
text[6].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[6].key = const_cast<png_charp>("ember_time");
|
||||
text[6].text = const_cast<png_charp>(comments.m_Runtime.c_str());
|
||||
text[7].compression = PNG_TEXT_COMPRESSION_zTXt;
|
||||
text[7].key = const_cast<png_charp>("ember_genome");
|
||||
text[7].text = const_cast<png_charp>(comments.m_Genome.c_str());
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
rows[i] = image + i * width * 4 * bytesPerChannel;
|
||||
@ -209,9 +184,37 @@ static bool WritePng(const char* filename, unsigned char* image, size_t width, s
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
//png_set_filter(png_ptr, 0, PNG_NO_FILTERS);
|
||||
|
||||
if (enableComments == 1)
|
||||
{
|
||||
png_text text[PNG_COMMENT_MAX];
|
||||
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[0].key = const_cast<png_charp>("ember_version");
|
||||
text[0].text = const_cast<png_charp>(EmberVersion());
|
||||
text[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[1].key = const_cast<png_charp>("ember_nickname");
|
||||
text[1].text = const_cast<png_charp>(nick.c_str());
|
||||
text[2].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[2].key = const_cast<png_charp>("ember_url");
|
||||
text[2].text = const_cast<png_charp>(url.c_str());
|
||||
text[3].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[3].key = const_cast<png_charp>("ember_id");
|
||||
text[3].text = const_cast<png_charp>(id.c_str());
|
||||
text[4].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[4].key = const_cast<png_charp>("ember_error_rate");
|
||||
text[4].text = const_cast<png_charp>(comments.m_Badvals.c_str());
|
||||
text[5].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[5].key = const_cast<png_charp>("ember_samples");
|
||||
text[5].text = const_cast<png_charp>(comments.m_NumIters.c_str());
|
||||
text[6].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[6].key = const_cast<png_charp>("ember_time");
|
||||
text[6].text = const_cast<png_charp>(comments.m_Runtime.c_str());
|
||||
text[7].compression = PNG_TEXT_COMPRESSION_zTXt;
|
||||
text[7].key = const_cast<png_charp>("ember_genome");
|
||||
text[7].text = const_cast<png_charp>(comments.m_Genome.c_str());
|
||||
png_set_text(png_ptr, info_ptr, text, PNG_COMMENT_MAX);
|
||||
}
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p align="center"><span style=" font-size:10pt;">Fractorium 23.23.8.1</span></p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><a href="http://fractorium.com"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html></string>
|
||||
<string><html><head/><body><p align="center"><span style=" font-size:10pt;">Fractorium 23.23.8.100</span></p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><a href="http://fractorium.com"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
|
@ -219,7 +219,7 @@ void CurvesGraphicsView::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
QGraphicsView::mousePressEvent(e);
|
||||
|
||||
if (e != nullptr)
|
||||
if (e == nullptr)
|
||||
return;
|
||||
|
||||
const auto thresh = devicePixelRatioF() * 4;
|
||||
|
@ -17,6 +17,12 @@ FinalRenderEmberControllerBase::FinalRenderEmberControllerBase(FractoriumFinalRe
|
||||
m_Settings = FractoriumSettings::DefInstance();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FinalRenderEmberController<T>::~FinalRenderEmberController()
|
||||
{
|
||||
m_ThreadedWriter.JoinAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the render by calling Abort().
|
||||
/// This will block until the cancelling is actually finished.
|
||||
@ -91,7 +97,6 @@ void FinalRenderEmberControllerBase::Output(const QString& s)
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTextOutput, "append", Qt::QueuedConnection, Q_ARG(const QString&, s));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Render a single ember.
|
||||
/// </summary>
|
||||
@ -103,36 +108,43 @@ template<typename T>
|
||||
bool FinalRenderEmberController<T>::RenderSingleEmber(Ember<T>& ember, bool fullRender, size_t& stripForProgress)
|
||||
{
|
||||
if (!m_Renderer.get())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = true;
|
||||
auto threadIndex = fullRender ? m_ThreadedWriter.Increment() : m_ThreadedWriter.Current();
|
||||
auto threadImage = m_ThreadedWriter.GetImage(threadIndex);
|
||||
ember.m_TemporalSamples = 1;//No temporal sampling.
|
||||
m_Renderer->SetEmber(ember, fullRender ? eProcessAction::FULL_RENDER : eProcessAction::KEEP_ITERATING, /* updatePointer */ true);
|
||||
m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
|
||||
m_Renderer->PrepFinalAccumVector(*threadImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
|
||||
m_Stats.Clear();
|
||||
m_RenderTimer.Tic();//Toc() is called in RenderComplete().
|
||||
StripsRender<T>(m_Renderer.get(), ember, m_FinalImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp,
|
||||
StripsRender<T>(m_Renderer.get(), ember, *threadImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp,
|
||||
[&](size_t strip) { stripForProgress = strip; },//Pre strip.
|
||||
[&](size_t strip) { m_Stats += m_Renderer->Stats(); },//Post strip.
|
||||
[&](size_t strip)//Error.
|
||||
{
|
||||
Output("Rendering failed.\n");
|
||||
m_Fractorium->ErrorReportToQTextEdit(m_Renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke.
|
||||
ret = false;
|
||||
m_Run = false;
|
||||
},
|
||||
[&](Ember<T>& finalEmber)
|
||||
{
|
||||
m_FinishedImageCount.fetch_add(1);
|
||||
|
||||
if (SaveCurrentRender(finalEmber) == "")
|
||||
m_Run = ret = false;
|
||||
|
||||
auto stats = m_Renderer->Stats();
|
||||
auto comments = m_Renderer->ImageComments(stats, 0, true);
|
||||
auto rasw = m_Renderer->FinalRasW();
|
||||
auto rash = m_Renderer->FinalRasH();
|
||||
auto png16 = m_FinalRenderDialog->Png16Bit();
|
||||
auto transparency = m_FinalRenderDialog->Transparency();
|
||||
RenderComplete(finalEmber);
|
||||
HandleFinishedProgress();
|
||||
auto writeThread = std::thread([ = ](Ember<T> threadEmber)//Pass ember by value.
|
||||
{
|
||||
if (SaveCurrentRender(threadEmber, comments, *threadImage, rasw, rash, png16, transparency) == "")
|
||||
m_Run = false;
|
||||
}, finalEmber);
|
||||
m_ThreadedWriter.SetThread(threadIndex, writeThread);
|
||||
});//Final strip.
|
||||
return ret;
|
||||
return m_Run;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -146,22 +158,17 @@ template<typename T>
|
||||
bool FinalRenderEmberController<T>::RenderSingleEmberFromSeries(std::atomic<size_t>* atomfTime, size_t index)
|
||||
{
|
||||
if (m_Renderers.size() <= index)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ftime;
|
||||
size_t finalImageIndex = 0;
|
||||
std::thread writeThread;
|
||||
vector<v4F> finalImages[2];
|
||||
EmberStats stats;
|
||||
EmberImageComments comments;
|
||||
Timing renderTimer;
|
||||
const auto renderer = m_Renderers[index].get();
|
||||
|
||||
if (renderer == nullptr)
|
||||
return false;
|
||||
|
||||
size_t ftime;
|
||||
Timing renderTimer;
|
||||
ThreadedWriter localThreadedWriter(16);//Use a local one for each renderer in a sequence instead of the class member.
|
||||
|
||||
//Render each image, cancelling if m_Run ever gets set to false.
|
||||
//The conditions of this loop use atomics to synchronize when running on multiple GPUs.
|
||||
//The order is reversed from the usual loop: rather than compare and increment the counter,
|
||||
@ -176,9 +183,12 @@ bool FinalRenderEmberController<T>::RenderSingleEmberFromSeries(std::atomic<size
|
||||
Output("Image " + ToString(ftime + 1ULL) + ":\n" + ComposePath(QString::fromStdString(m_EmberFile.Get(ftime)->m_Name)));
|
||||
renderer->Reset();//Have to manually set this since the ember is not set each time through.
|
||||
renderTimer.Tic();//Toc() is called in RenderComplete().
|
||||
auto threadIndex = localThreadedWriter.Increment();
|
||||
auto threadImage = localThreadedWriter.GetImage(threadIndex);
|
||||
//renderer->PrepFinalAccumVector(threadImage);
|
||||
|
||||
//Can't use strips render here. Run() must be called directly for animation.
|
||||
if (renderer->Run(finalImages[finalImageIndex], T(ftime)) != eRenderStatus::RENDER_OK)
|
||||
if (renderer->Run(*threadImage, T(ftime)) != eRenderStatus::RENDER_OK)
|
||||
{
|
||||
Output("Rendering failed.\n");
|
||||
m_Fractorium->ErrorReportToQTextEdit(renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke.
|
||||
@ -188,31 +198,33 @@ bool FinalRenderEmberController<T>::RenderSingleEmberFromSeries(std::atomic<size
|
||||
}
|
||||
else
|
||||
{
|
||||
Join(writeThread);
|
||||
stats = renderer->Stats();
|
||||
comments = renderer->ImageComments(stats, 0, true);
|
||||
writeThread = std::thread([&](size_t tempTime, size_t threadFinalImageIndex)
|
||||
{
|
||||
if (SaveCurrentRender(*m_EmberFile.Get(tempTime),
|
||||
comments,//These all don't change during the renders, so it's ok to access them in the thread.
|
||||
finalImages[threadFinalImageIndex],
|
||||
renderer->FinalRasW(),
|
||||
renderer->FinalRasH(),
|
||||
m_FinalRenderDialog->Png16Bit(),
|
||||
m_FinalRenderDialog->Transparency()) == "")
|
||||
m_Run = false;
|
||||
}, ftime, finalImageIndex);
|
||||
auto stats = renderer->Stats();
|
||||
auto comments = renderer->ImageComments(stats, 0, true);
|
||||
auto w = renderer->FinalRasW();
|
||||
auto h = renderer->FinalRasH();
|
||||
auto ember = m_EmberFile.Get(ftime);
|
||||
m_FinishedImageCount.fetch_add(1);
|
||||
RenderComplete(*m_EmberFile.Get(ftime), stats, renderTimer);
|
||||
RenderComplete(*ember, stats, renderTimer);
|
||||
|
||||
if (!index)//Only first device has a progress callback, so it also makes sense to only manually set the progress on the first device as well.
|
||||
HandleFinishedProgress();
|
||||
}
|
||||
|
||||
finalImageIndex ^= 1;//Toggle the index.
|
||||
auto writeThread = std::thread([ = ]()
|
||||
{
|
||||
if (SaveCurrentRender(*ember,
|
||||
comments,//These all don't change during the renders, so it's ok to access them in the thread.
|
||||
*threadImage,
|
||||
w,
|
||||
h,
|
||||
m_FinalRenderDialog->Png16Bit(),
|
||||
m_FinalRenderDialog->Transparency()) == "")
|
||||
m_Run = false;
|
||||
});
|
||||
localThreadedWriter.SetThread(threadIndex, writeThread);
|
||||
}
|
||||
}
|
||||
|
||||
Join(writeThread);//One final check to make sure all writing is done before exiting this thread.
|
||||
localThreadedWriter.JoinAll();//One final check to make sure all writing is done before exiting this thread.
|
||||
return m_Run;
|
||||
}
|
||||
|
||||
@ -223,7 +235,8 @@ bool FinalRenderEmberController<T>::RenderSingleEmberFromSeries(std::atomic<size
|
||||
/// <param name="finalRender">Pointer to the final render dialog</param>
|
||||
template<typename T>
|
||||
FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender)
|
||||
: FinalRenderEmberControllerBase(finalRender)
|
||||
: FinalRenderEmberControllerBase(finalRender),
|
||||
m_ThreadedWriter(16)
|
||||
{
|
||||
m_FinalPreviewRenderer = make_unique<FinalRenderPreviewRenderer<T>>(this);
|
||||
//The main rendering function which will be called in a Qt thread.
|
||||
@ -321,7 +334,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
break;
|
||||
|
||||
Output("Image " + ToString<qulonglong>(m_FinishedImageCount.load() + 1) + ":\n" + ComposePath(QString::fromStdString(it.m_Name)));
|
||||
RenderSingleEmber(it, /* fullRender */ true, currentStripForProgress);
|
||||
RenderSingleEmber(it, true, currentStripForProgress);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -335,18 +348,21 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
m_ImageCount = 1;
|
||||
m_Ember->m_TemporalSamples = 1;
|
||||
m_Fractorium->m_Controller->ParamsToEmber(*m_Ember, true);//Update color and filter params from the main window controls, which only affect the filter and/or final accumulation stage.
|
||||
RenderSingleEmber(*m_Ember, /* fullRender= */ !isBump, currentStripForProgress);
|
||||
RenderSingleEmber(*m_Ember, !isBump, currentStripForProgress);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("No renderer present, aborting.");
|
||||
}
|
||||
|
||||
m_ThreadedWriter.JoinAll();
|
||||
const QString totalTimeString = m_Run ? "All renders completed in: " + QString::fromStdString(m_TotalTimer.Format(m_TotalTimer.Toc())) + "."
|
||||
: "Render aborted.";
|
||||
Output(totalTimeString);
|
||||
QFile::remove(backup);
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog, "Pause", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderSaveAgainAsButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get()));//Can do save again with variable number of strips.
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderBumpQualityStartButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get() && m_GuiState.m_Strips == 1));
|
||||
m_Run = false;
|
||||
};
|
||||
}
|
||||
@ -815,6 +831,8 @@ QString FinalRenderEmberController<T>::SaveCurrentAgain()
|
||||
minde != m_Ember->m_MinRadDE ||
|
||||
maxde != m_Ember->m_MaxRadDE ||
|
||||
curvede != m_Ember->m_CurveDE;
|
||||
auto threadIndex = m_ThreadedWriter.Current();
|
||||
auto threadImage = m_ThreadedWriter.GetImage(threadIndex);
|
||||
|
||||
//This is sort of a hack outside of the normal rendering process above.
|
||||
if (dofilterandaccum ||
|
||||
@ -831,14 +849,18 @@ QString FinalRenderEmberController<T>::SaveCurrentAgain()
|
||||
m_Ember->m_TemporalSamples = 1;
|
||||
m_Renderer->m_ProgressParameter = reinterpret_cast<void*>(¤tStripForProgress);//Need to reset this because it was set to a local variable within the render thread.
|
||||
m_Renderer->SetEmber(*m_Ember, dofilterandaccum ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY);
|
||||
m_Renderer->Run(m_FinalImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp);
|
||||
m_Renderer->Run(*threadImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp);
|
||||
m_FinishedImageCount.fetch_add(1);
|
||||
HandleFinishedProgress();
|
||||
m_Run = false;
|
||||
}
|
||||
|
||||
auto stats = m_Renderer->Stats();
|
||||
auto comments = m_Renderer->ImageComments(stats, 0, true);
|
||||
return SaveCurrentRender(*m_Ember, comments, *threadImage, m_Renderer->FinalRasW(), m_Renderer->FinalRasH(), m_FinalRenderDialog->Png16Bit(), m_FinalRenderDialog->Transparency());
|
||||
}
|
||||
|
||||
return SaveCurrentRender(*m_Ember);
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -941,8 +963,6 @@ void FinalRenderEmberController<T>::HandleFinishedProgress()
|
||||
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, static_cast<int>((float(finishedCountCached) / static_cast<float>(m_ImageCount)) * 100)));
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(const QString&, ToString<qulonglong>(finishedCountCached) + " / " + ToString<qulonglong>(m_ImageCount)));
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderSaveAgainAsButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get()));//Can do save again with variable number of strips.
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderBumpQualityStartButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get() && m_GuiState.m_Strips == 1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -106,7 +106,7 @@ class FinalRenderEmberController : public FinalRenderEmberControllerBase
|
||||
|
||||
public:
|
||||
FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender);
|
||||
virtual ~FinalRenderEmberController() { }
|
||||
virtual ~FinalRenderEmberController();
|
||||
|
||||
//Virtual functions overridden from FractoriumEmberControllerBase.
|
||||
void SetEmberFile(const EmberFile<float>& emberFile, bool move) override;
|
||||
@ -159,6 +159,7 @@ protected:
|
||||
EmberToXml<T> m_XmlWriter;
|
||||
unique_ptr<FinalRenderPreviewRenderer<T>> m_FinalPreviewRenderer;
|
||||
vector<unique_ptr<EmberNs::Renderer<T, float>>> m_Renderers;
|
||||
ThreadedWriter m_ThreadedWriter;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -69,7 +69,7 @@ Fractorium::Fractorium(QWidget* p)
|
||||
m_VarDialog = new FractoriumVariationsDialog(this);
|
||||
m_AboutDialog = new FractoriumAboutDialog(this);
|
||||
//Put the about dialog in the screen center.
|
||||
m_AboutDialogCentered = false;
|
||||
m_AboutDialogCentered = false;
|
||||
connect(m_ColorDialog, SIGNAL(colorSelected(const QColor&)), this, SLOT(OnColorSelected(const QColor&)), Qt::QueuedConnection);
|
||||
m_XformComboColors[i++] = QColor(0XFF, 0X00, 0X00);
|
||||
m_XformComboColors[i++] = QColor(0XCC, 0XCC, 0X00);
|
||||
@ -755,11 +755,11 @@ void Fractorium::showEvent(QShowEvent* e)
|
||||
emit qGuiApp->focusWindowChanged(windowHandle());
|
||||
QMainWindow::showEvent(e);
|
||||
|
||||
if(!m_AboutDialogCentered)
|
||||
{
|
||||
m_AboutDialogCentered = true;
|
||||
QTimer::singleShot(100, this, SLOT(WindowShown()));
|
||||
}
|
||||
if (!m_AboutDialogCentered)
|
||||
{
|
||||
m_AboutDialogCentered = true;
|
||||
QTimer::singleShot(100, this, SLOT(WindowShown()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -769,10 +769,10 @@ void Fractorium::showEvent(QShowEvent* e)
|
||||
/// </summary>
|
||||
void Fractorium::WindowShown()
|
||||
{
|
||||
//Put the about dialog in the screen center.
|
||||
auto screen = QGuiApplication::screenAt(pos());
|
||||
auto geom = screen->availableGeometry();
|
||||
m_AboutDialog->move(geom.center() - m_AboutDialog->rect().center());
|
||||
//Put the about dialog in the screen center.
|
||||
auto screen = QGuiApplication::screenAt(pos());
|
||||
auto geom = screen->availableGeometry();
|
||||
m_AboutDialog->move(geom.center() - m_AboutDialog->rect().center());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -358,6 +358,7 @@ public slots:
|
||||
void OnRandomXaosButtonClicked(bool checked);
|
||||
void OnAddLayerButtonClicked(bool checked);
|
||||
void OnTransposeXaosButtonClicked(bool checked);
|
||||
void OnToggleXaosButtonClicked(bool checked);
|
||||
void OnXaosRowDoubleClicked(int logicalIndex);
|
||||
void OnXaosColDoubleClicked(int logicalIndex);
|
||||
void OnXaosHScrollValueChanged(int value);
|
||||
@ -398,7 +399,7 @@ public slots:
|
||||
void SetTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h);
|
||||
|
||||
private slots:
|
||||
void WindowShown();
|
||||
void WindowShown();
|
||||
|
||||
public:
|
||||
//template<typename spinType, typename valType>//See below.
|
||||
@ -626,7 +627,7 @@ private:
|
||||
std::unordered_map<QString, std::pair<int, int>> m_HeightPresets;
|
||||
|
||||
bool m_PreviousAffineState[4];
|
||||
bool m_AboutDialogCentered;
|
||||
bool m_AboutDialogCentered;
|
||||
int m_FontSize;
|
||||
int m_VarSortMode;
|
||||
int m_PaletteSortMode;
|
||||
|
@ -2000,6 +2000,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="ToggleXaosButton">
|
||||
<property name="toolTip">
|
||||
<string>Toggle whether to use xaos</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Toggle Xaos</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -6025,7 +6035,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>3</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>10</number>
|
||||
@ -6046,20 +6056,15 @@
|
||||
<property name="text">
|
||||
<string>Variation</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Red: Uses non-standard assignment which means direct assignment for regular variations, sum for pre/post. Order matters for these variations, which can be adjusted by dragging them within the tree on the Summary Tab.</p><p>Green: Uses direct color.</p><p>Blue: Uses an internal variation state.</p></body></html></string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Weight</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Red: Uses non-standard assignment which means direct assignment for regular variations, sum for pre/post. Order matters for these variations, which can be adjusted by dragging them within the tree on the Summary Tab.</p><p>Green: Uses direct color.</p><p>Blue: Uses an internal variation state.</p></body></html></string>
|
||||
</property>
|
||||
</column>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Spherical</string>
|
||||
|
@ -20,7 +20,6 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor
|
||||
m_RenderRestartTimer = make_unique<QTimer>(m_Fractorium);
|
||||
m_AnimateTimer = make_unique<QTimer>(m_Fractorium);
|
||||
m_AnimateTimer->stop();
|
||||
|
||||
m_Fractorium->connect(m_RenderRestartTimer.get(), &QTimer::timeout, [&]() { m_Fractorium->StartRenderTimer(false); });//It's ok to pass false for the first shot because creating the controller will start the preview renders.
|
||||
// XXX: why not SLOT(SequenceAnimateNextFrame())?
|
||||
m_Fractorium->connect(m_AnimateTimer.get(), &QTimer::timeout, [&]() { SequenceAnimateNextFrame(); });
|
||||
@ -115,7 +114,7 @@ FractoriumEmberController<T>::~FractoriumEmberController() { }
|
||||
/// These are used to preserve the current ember/file when switching between renderers.
|
||||
/// Note that some precision will be lost when going from double to float.
|
||||
/// </summary>
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<float>(ember, verbatim, updatePointer); }
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer, int xformIndex) { SetEmberPrivate<float>(ember, verbatim, updatePointer, xformIndex); }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile, bool move) { move ? m_EmberFile = std::move(emberFile) : m_EmberFile = emberFile; }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile, bool sequence, std::function<void(Ember<float>& ember)> perEmberOperation)
|
||||
@ -132,10 +131,12 @@ template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void FractoriumEmberController<T>::CopyXaosToggleEmber(Ember<float>& ember) { ember = m_XaosToggleEmber; }
|
||||
template <typename T> void FractoriumEmberController<T>::SetXaosToggleEmber(const Ember<float>& ember) { m_XaosToggleEmber = ember; }
|
||||
template <typename T> void FractoriumEmberController<T>::SetTempPalette(const Palette<float>& palette) { m_TempPalette = palette; }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyTempPalette(Palette<float>& palette) { palette = m_TempPalette; }
|
||||
#ifdef DO_DOUBLE
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<double>(ember, verbatim, updatePointer); }
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer, int xformIndex) { SetEmberPrivate<double>(ember, verbatim, updatePointer, xformIndex); }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
|
||||
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile, bool move) { move ? m_EmberFile = std::move(emberFile) : m_EmberFile = emberFile; }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile, bool sequence, std::function<void(Ember<double>& ember)> perEmberOperation)
|
||||
@ -152,6 +153,8 @@ template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void FractoriumEmberController<T>::CopyXaosToggleEmber(Ember<double>& ember) { ember = m_XaosToggleEmber; }
|
||||
template <typename T> void FractoriumEmberController<T>::SetXaosToggleEmber(const Ember<double>& ember) { m_XaosToggleEmber = ember; }
|
||||
template <typename T> void FractoriumEmberController<T>::SetTempPalette(const Palette<double>& palette) { m_TempPalette = palette; }
|
||||
template <typename T> void FractoriumEmberController<T>::CopyTempPalette(Palette<double>& palette) { palette = m_TempPalette; }
|
||||
#endif
|
||||
@ -166,6 +169,8 @@ void FractoriumEmberController<T>::ConstrainDimensions(Ember<T>& ember)
|
||||
|
||||
/// <summary>
|
||||
/// Set the ember at the specified index from the currently opened file as the current Ember.
|
||||
/// Also attempt to keep the same xform inxed selected, which is useful when switching between many
|
||||
/// similar embers when setting up animation keyframes.
|
||||
/// Clears the undo state.
|
||||
/// Resets the rendering process.
|
||||
/// </summary>
|
||||
@ -176,9 +181,10 @@ void FractoriumEmberController<T>::SetEmber(size_t index, bool verbatim)
|
||||
{
|
||||
if (index < m_EmberFile.Size())
|
||||
{
|
||||
auto currentXformIndex = m_Fractorium->ui.CurrentXformCombo->currentIndex();
|
||||
m_Fractorium->SelectLibraryItem(index);
|
||||
ClearUndo();
|
||||
SetEmber(*m_EmberFile.Get(index), verbatim, true);
|
||||
SetEmber(*m_EmberFile.Get(index), verbatim, true, currentXformIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,9 +335,10 @@ void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*, siz
|
||||
/// <param name="ember">The ember to set as the current</param>
|
||||
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
|
||||
/// <param name="updatePointer">If true, update the current ember pointer to the address of the one passed in.</param>
|
||||
/// <param name="xformIndex">The xform index to select as the current one</param>
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer)
|
||||
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer, int xformIndex)
|
||||
{
|
||||
if (ember.m_Name != m_Ember.m_Name)
|
||||
m_LastSaveCurrent = "";
|
||||
@ -339,6 +346,7 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
|
||||
const auto w = m_Ember.m_FinalRasW;//Cache values for use below.
|
||||
const auto h = m_Ember.m_FinalRasH;
|
||||
m_Ember = ember;
|
||||
m_XaosToggleEmber.Clear();
|
||||
|
||||
if (updatePointer && (typeid(T) == typeid(U)))
|
||||
m_EmberFilePointer = (Ember<T>*)&ember;
|
||||
@ -360,7 +368,7 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
|
||||
const auto filename = path.toStdString() + "/last.flame";
|
||||
writer.Save(filename, m_Ember, 0, true, true, false, true, true);
|
||||
m_GLController->ResetMouseState();
|
||||
FillXforms();//Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
|
||||
FillXforms(xformIndex);//Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
|
||||
FillParamTablesAndPalette();
|
||||
FillCurvesControl();
|
||||
FillSummary();
|
||||
|
@ -57,17 +57,21 @@ public:
|
||||
virtual ~FractoriumEmberControllerBase();
|
||||
|
||||
//Embers.
|
||||
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { }
|
||||
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer, int xformIndex) { }
|
||||
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
|
||||
virtual void SetEmberFile(const EmberFile<float>& emberFile, bool move) { }
|
||||
virtual void CopyEmberFile(EmberFile<float>& emberFile, bool sequence, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }
|
||||
virtual void CopyXaosToggleEmber(Ember<float>& ember) { }
|
||||
virtual void SetXaosToggleEmber(const Ember<float>& ember) { }
|
||||
virtual void SetTempPalette(const Palette<float>& palette) { }
|
||||
virtual void CopyTempPalette(Palette<float>& palette) { }
|
||||
#ifdef DO_DOUBLE
|
||||
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { }
|
||||
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer, int xformIndex) { }
|
||||
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
|
||||
virtual void SetEmberFile(const EmberFile<double>& emberFile, bool move) { }
|
||||
virtual void CopyEmberFile(EmberFile<double>& emberFile, bool sequence, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
|
||||
virtual void CopyXaosToggleEmber(Ember<double>& ember) { }
|
||||
virtual void SetXaosToggleEmber(const Ember<double>& ember) { }
|
||||
virtual void SetTempPalette(const Palette<double>& palette) { }
|
||||
virtual void CopyTempPalette(Palette<double>& palette) { }
|
||||
#endif
|
||||
@ -252,6 +256,7 @@ public:
|
||||
virtual void RandomXaos() { }
|
||||
virtual void AddLayer(int xforms) { }
|
||||
virtual void TransposeXaos() { }
|
||||
virtual void ToggleXaos() { }
|
||||
|
||||
//Palette.
|
||||
virtual size_t InitPaletteList(const QString& s) { return 0; }
|
||||
@ -352,17 +357,21 @@ public:
|
||||
virtual ~FractoriumEmberController();
|
||||
|
||||
//Embers.
|
||||
void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) override;
|
||||
void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer, int xformIndex) override;
|
||||
void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
|
||||
void SetEmberFile(const EmberFile<float>& emberFile, bool move) override;
|
||||
void CopyEmberFile(EmberFile<float>& emberFile, bool sequence, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
|
||||
void CopyXaosToggleEmber(Ember<float>& ember) override;
|
||||
void SetXaosToggleEmber(const Ember<float>& ember) override;
|
||||
void SetTempPalette(const Palette<float>& palette) override;
|
||||
void CopyTempPalette(Palette<float>& palette) override;
|
||||
#ifdef DO_DOUBLE
|
||||
void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) override;
|
||||
void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer, int xformIndex) override;
|
||||
void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
|
||||
void SetEmberFile(const EmberFile<double>& emberFile, bool move) override;
|
||||
void CopyEmberFile(EmberFile<double>& emberFile, bool sequence, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
|
||||
void CopyXaosToggleEmber(Ember<double>& ember) override;
|
||||
void SetXaosToggleEmber(const Ember<double>& ember) override;
|
||||
void SetTempPalette(const Palette<double>& palette) override;
|
||||
void CopyTempPalette(Palette<double>& palette) override;
|
||||
#endif
|
||||
@ -542,6 +551,7 @@ public:
|
||||
void FilteredVariations() override;
|
||||
void FillVariationTreeWithCurrentXform() override;
|
||||
void FillVariationTreeWithXform(Xform<T>* xform);
|
||||
QIcon MakeVariationIcon(const Variation<T>* var);
|
||||
|
||||
//Xforms Xaos.
|
||||
void FillXaos() override;
|
||||
@ -551,6 +561,7 @@ public:
|
||||
void RandomXaos() override;
|
||||
void AddLayer(int xforms) override;
|
||||
void TransposeXaos() override;
|
||||
void ToggleXaos() override;
|
||||
|
||||
//Xforms Selection.
|
||||
virtual QString MakeXformCaption(size_t i) override;
|
||||
@ -584,7 +595,7 @@ public:
|
||||
private:
|
||||
//Embers.
|
||||
void ApplyXmlSavingTemplate(Ember<T>& ember);
|
||||
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer);
|
||||
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer, int xformIndex);
|
||||
|
||||
//Params.
|
||||
template <typename U> void ParamsToEmberPrivate(Ember<U>& ember, bool imageParamsOnly);
|
||||
@ -609,6 +620,7 @@ private:
|
||||
vector<T> m_TempOpacities;
|
||||
vector<T> m_NormalizedWeights;
|
||||
Ember<T> m_Ember;
|
||||
Ember<T> m_XaosToggleEmber;
|
||||
Ember<T>* m_EmberFilePointer = nullptr;
|
||||
EmberFile<T> m_EmberFile;
|
||||
EmberFile<T> m_SequenceFile;
|
||||
|
@ -163,6 +163,8 @@ void FractoriumEmberController<T>::FillSummary()
|
||||
vitem->setText(0, QString::fromStdString(var->Name()));
|
||||
vitem->setText(1, QLocale::system().toString(var->m_Weight, pc, vp).rightJustified(vlen, ' '));
|
||||
vitem->setFlags(draggable);
|
||||
auto qi = MakeVariationIcon(var);
|
||||
vitem->setIcon(0, qi);
|
||||
|
||||
if (const auto parVar = dynamic_cast<ParametricVariation<T>*>(var))
|
||||
{
|
||||
|
@ -672,13 +672,13 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
|
||||
return;
|
||||
}
|
||||
|
||||
if (framesPerRot > 1 && !rots)//Because framesPerRot control has a min value of 1, check greater than 1. Also don't need to check the inverse like in EmberGenome.
|
||||
{
|
||||
QMessageBox::critical(m_Fractorium, "Animation sequence parameters error",
|
||||
"Frames per rot cannot be greater than one while Rotations is zero. Setting it to 1.");
|
||||
ui.SequenceFramesPerRotSpinBox->setValue(1);
|
||||
return;
|
||||
}
|
||||
//if (framesPerRot > 1 && !rots)//Because framesPerRot control has a min value of 1, check greater than 1. Also don't need to check the inverse like in EmberGenome.
|
||||
//{
|
||||
//QMessageBox::critical(m_Fractorium, "Animation sequence parameters error",
|
||||
// "Frames per rot cannot be greater than one while Rotations is zero. Setting it to 1.");
|
||||
//ui.SequenceFramesPerRotSpinBox->setValue(1);
|
||||
//return;
|
||||
//}
|
||||
}
|
||||
|
||||
SheepTools<T, float> tools(palettePath, EmberCommon::CreateRenderer<T>(eRendererType::CPU_RENDERER, devices, false, 0, emberReport));
|
||||
@ -695,8 +695,10 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
|
||||
|
||||
if (randFramesRot)
|
||||
frames = ui.SequenceRandomFramesPerRotMaxSpinBox->value();
|
||||
else
|
||||
else if (rots)
|
||||
frames = ui.SequenceFramesPerRotSpinBox->value();
|
||||
else
|
||||
frames = 1;
|
||||
|
||||
if (randRot)
|
||||
frames *= ui.SequenceRandomRotationsMaxSpinBox->value();
|
||||
|
@ -162,14 +162,15 @@ void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controlle
|
||||
template <typename T>
|
||||
void FractoriumEmberController<T>::CopyFlameInCurrentFile()
|
||||
{
|
||||
auto ember = m_Ember;
|
||||
StopAllPreviewRenderers();
|
||||
auto ember = m_Ember;
|
||||
auto insertEmberIndex = m_Fractorium->ui.LibraryTree->currentIndex().row() + 1;
|
||||
ember.m_Name = EmberFile<T>::DefaultEmberName(m_EmberFile.Size() + 1).toStdString();
|
||||
ember.m_Index = m_EmberFile.Size();
|
||||
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
|
||||
ember.m_Index = insertEmberIndex;//Will be overwritten below in UpdateLibraryTree().
|
||||
m_EmberFile.m_Embers.insert(Advance(m_EmberFile.m_Embers.begin(), insertEmberIndex), ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
|
||||
m_EmberFile.MakeNamesUnique();
|
||||
UpdateLibraryTree();
|
||||
SetEmber(m_EmberFile.Size() - 1, false);
|
||||
FillLibraryTree(insertEmberIndex);
|
||||
SetEmber(insertEmberIndex, false);
|
||||
}
|
||||
|
||||
void Fractorium::OnActionCopyFlameInCurrentFile(bool checked) { m_Controller->CopyFlameInCurrentFile(); }
|
||||
@ -590,7 +591,7 @@ void FractoriumEmberController<T>::Undo()
|
||||
int index = m_Ember.GetTotalXformIndex(current, forceFinal);
|
||||
m_LastEditWasUndoRedo = true;
|
||||
m_UndoIndex = std::max<size_t>(0u, m_UndoIndex - 1u);
|
||||
SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list.
|
||||
SetEmber(m_UndoList[m_UndoIndex], true, false, index);//Don't update pointer because it's coming from the undo list.
|
||||
m_EditState = eEditUndoState::UNDO_REDO;
|
||||
|
||||
if (index >= 0 && index < m_Fractorium->ui.CurrentXformCombo->count())
|
||||
@ -616,7 +617,7 @@ void FractoriumEmberController<T>::Redo()
|
||||
int index = m_Ember.GetTotalXformIndex(current, forceFinal);
|
||||
m_LastEditWasUndoRedo = true;
|
||||
m_UndoIndex = std::min<size_t>(m_UndoIndex + 1, m_UndoList.size() - 1);
|
||||
SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list.
|
||||
SetEmber(m_UndoList[m_UndoIndex], true, false, index);//Don't update pointer because it's coming from the undo list.
|
||||
m_EditState = eEditUndoState::UNDO_REDO;
|
||||
|
||||
if (index >= 0 && index < m_Fractorium->ui.CurrentXformCombo->count())
|
||||
|
@ -438,7 +438,7 @@ void FractoriumEmberController<T>::ResizeAndScale(int width, int height, eScaleT
|
||||
{
|
||||
UpdateAll([&](Ember<T>& ember, bool isMain)
|
||||
{
|
||||
m_Ember.SetSizeAndAdjustScale(width, height, false, scaleType);
|
||||
ember.SetSizeAndAdjustScale(width, height, false, scaleType);
|
||||
}, true, eProcessAction::FULL_RENDER, m_Fractorium->ApplyAll());
|
||||
m_Fractorium->m_ScaleSpin->SetValueStealth(m_Ember.m_PixelsPerUnit);
|
||||
m_Fractorium->OnActionResetScale(true);
|
||||
@ -521,11 +521,6 @@ template <typename T> void FractoriumEmberController<T>::RotateChanged(double d)
|
||||
}
|
||||
void Fractorium::OnRotateChanged(double d)
|
||||
{
|
||||
if (d < -180)
|
||||
d = 180 - ((-d + m_RotateSpin->value()) - (180 + m_RotateSpin->value()));
|
||||
else if (d > 180)
|
||||
d = -180 + ((d - m_RotateSpin->value()) - (180 - m_RotateSpin->value()));
|
||||
|
||||
m_Controller->RotateChanged(d); // d is ever between -180 and +180
|
||||
}
|
||||
|
||||
|
@ -758,9 +758,11 @@ bool Fractorium::CreateControllerFromOptions()
|
||||
#ifdef DO_DOUBLE
|
||||
EmberFile<double> efd;
|
||||
Palette<double> tempPalette;
|
||||
Ember<double> xaosToggle;
|
||||
#else
|
||||
EmberFile<float> efd;
|
||||
Palette<float> tempPalette;
|
||||
Ember<float> xaosToggle;
|
||||
#endif
|
||||
const QModelIndex index = ui.LibraryTree->currentIndex();
|
||||
ui.LibraryTree->clear();//This must be here before FillLibraryTree() is called below, else a spurious EmberTreeItemChanged event will be called on a deleted object.
|
||||
@ -774,6 +776,7 @@ bool Fractorium::CreateControllerFromOptions()
|
||||
current = m_Controller->SaveCurrentToOpenedFile(false);
|
||||
//Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
|
||||
//m_Controller->CopyEmberFile(efd);
|
||||
m_Controller->CopyXaosToggleEmber(xaosToggle);
|
||||
#ifdef DO_DOUBLE
|
||||
m_Controller->CopyEmberFile(efd, false, [&](Ember<double>& ember) { });
|
||||
#else
|
||||
@ -804,6 +807,7 @@ bool Fractorium::CreateControllerFromOptions()
|
||||
//will apply the palette adjustments.
|
||||
m_Controller->FillLibraryTree(index.row());
|
||||
m_Controller->SetEmber(current, true);
|
||||
m_Controller->SetXaosToggleEmber(xaosToggle);
|
||||
m_Controller->LockedScale(scale);
|
||||
//Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above.
|
||||
//It's a corner case, but doesn't seem to matter.
|
||||
|
@ -11,6 +11,9 @@ void Fractorium::InitXaosUI()
|
||||
int spinHeight = 20;
|
||||
ui.XaosTableView->verticalHeader()->setSectionsClickable(true);
|
||||
ui.XaosTableView->horizontalHeader()->setSectionsClickable(true);
|
||||
auto ttstr = "<html><head/><body><p>Double click to toggle all table spinner values in one row/col.</p><p>If any cell in the row is non zero, set all cells to zero, else 1.</p><p>If shift is held down, reverse the logic.</p><p>If ctrl is held down, set each cell to a random 0 or 1.</p></body></html>";
|
||||
ui.XaosTableView->horizontalHeader()->setToolTip(ttstr);
|
||||
ui.XaosTableView->verticalHeader()->setToolTip(ttstr);
|
||||
m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1, false);
|
||||
m_XaosSpinBox->DoubleClick(true);
|
||||
m_XaosSpinBox->DoubleClickZero(1);
|
||||
@ -24,6 +27,7 @@ void Fractorium::InitXaosUI()
|
||||
connect(ui.ClearXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnClearXaosButtonClicked(bool)), Qt::QueuedConnection);
|
||||
connect(ui.RandomXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomXaosButtonClicked(bool)), Qt::QueuedConnection);
|
||||
connect(ui.TransposeXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnTransposeXaosButtonClicked(bool)), Qt::QueuedConnection);
|
||||
connect(ui.ToggleXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnToggleXaosButtonClicked(bool)), Qt::QueuedConnection);
|
||||
connect(ui.AddLayerButton, SIGNAL(clicked(bool)), this, SLOT(OnAddLayerButtonClicked(bool)), Qt::QueuedConnection);
|
||||
connect(ui.XaosTableView->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosRowDoubleClicked(int)), Qt::QueuedConnection);
|
||||
connect(ui.XaosTableView->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosColDoubleClicked(int)), Qt::QueuedConnection);
|
||||
@ -59,22 +63,22 @@ void FractoriumEmberController<T>::FillXaos()
|
||||
template <typename T>
|
||||
void FractoriumEmberController<T>::FillAppliedXaos()
|
||||
{
|
||||
m_Ember.CalcNormalizedWeights(m_NormalizedWeights);
|
||||
std::vector<T> weights;
|
||||
auto ct = int(XformCount());
|
||||
|
||||
for (int i = 0, count = int(XformCount()); i < count; i++)//Column.
|
||||
for (int i = 0, count = ct; i < count; i++)
|
||||
weights.push_back(m_Ember.GetXform(i)->m_Weight);
|
||||
|
||||
for (int i = 0, count = ct; i < count; i++)//Column.
|
||||
{
|
||||
if (const auto xform = m_Ember.GetXform(i))
|
||||
{
|
||||
T norm = 0;
|
||||
double start = 0, offset = 0;
|
||||
auto tempweights = m_NormalizedWeights;
|
||||
auto tempweights = weights;
|
||||
|
||||
for (int j = 0; j < count; j++)//Row.
|
||||
{
|
||||
tempweights[j] *= xform->Xaos(j);
|
||||
QModelIndex index = m_Fractorium->m_AppliedXaosTableModel->index(j, i, QModelIndex());//j and i are intentionally swapped here.
|
||||
m_Fractorium->m_AppliedXaosTableModel->setData(index, TruncPrecision(xform->Xaos(j) * xform->m_Weight, 4));//Applied xaos is just a read only table for display purposes.
|
||||
}
|
||||
|
||||
QPixmap pixmap(m_Fractorium->ui.XaosAppliedTableView->columnWidth(i) - 8, m_Fractorium->ui.XaosTableView->rowHeight(0) * count);
|
||||
QPainter painter(&pixmap);
|
||||
@ -84,6 +88,13 @@ void FractoriumEmberController<T>::FillAppliedXaos()
|
||||
|
||||
for (auto& w : tempweights) w = norm == static_cast<T>(0) ? static_cast<T>(0) : w / norm;
|
||||
|
||||
for (int j = 0; j < count; j++)//Row.
|
||||
{
|
||||
auto normXaosAppliedWeight = tempweights[j];
|
||||
QModelIndex index = m_Fractorium->m_AppliedXaosTableModel->index(j, i, QModelIndex());//j and i are intentionally swapped here.
|
||||
m_Fractorium->m_AppliedXaosTableModel->setData(index, TruncPrecision(normXaosAppliedWeight, 4));//Applied xaos is just a read only table for display purposes.
|
||||
}
|
||||
|
||||
if (norm)
|
||||
{
|
||||
for (size_t i = 0; i < tempweights.size() && offset <= pixmap.height(); i++)
|
||||
@ -309,6 +320,48 @@ void FractoriumEmberController<T>::TransposeXaos()
|
||||
|
||||
void Fractorium::OnTransposeXaosButtonClicked(bool checked) { m_Controller->TransposeXaos(); }
|
||||
|
||||
/// <summary>
|
||||
/// Toggle whether to use xaos or not by saving/restoring a backup flame.
|
||||
/// Resets the rendering process.
|
||||
/// </summary>
|
||||
template <typename T>
|
||||
void FractoriumEmberController<T>::ToggleXaos()
|
||||
{
|
||||
Update([&]
|
||||
{
|
||||
if (m_Ember.XaosPresent())
|
||||
{
|
||||
m_XaosToggleEmber = m_Ember;
|
||||
m_Ember.ClearXaos();
|
||||
}
|
||||
else if (m_XaosToggleEmber.XaosPresent())
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while (auto xform = m_Ember.GetXform(i))
|
||||
{
|
||||
auto backupXform = m_XaosToggleEmber.GetXform(i);
|
||||
|
||||
if (backupXform)
|
||||
{
|
||||
for (size_t j = 0; j < m_Ember.XformCount(); j++)
|
||||
xform->SetXaos(j, TruncPrecision(backupXform->Xaos(j), XAOS_PREC));
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
m_XaosToggleEmber.Clear();
|
||||
}
|
||||
});
|
||||
FillXaos();
|
||||
FillAppliedXaos();
|
||||
}
|
||||
|
||||
void Fractorium::OnToggleXaosButtonClicked(bool checked) { m_Controller->ToggleXaos(); }
|
||||
|
||||
/// <summary>
|
||||
/// Toggle all xaos values in one row on left mouse button double click and resize all cells to fit their data.
|
||||
/// Skip toggling and only refit on right mouse button double click.
|
||||
|
@ -670,10 +670,8 @@ void FractoriumEmberController<T>::FillXforms(int index)
|
||||
|
||||
m_Fractorium->m_XformsSelectionLayout->blockSignals(false);
|
||||
combo->blockSignals(false);
|
||||
|
||||
if (index < combo->count())
|
||||
combo->setCurrentIndex(index);
|
||||
|
||||
index = index >= 0 && index < combo->count() ? index : 0;
|
||||
combo->setCurrentIndex(index);
|
||||
m_Fractorium->ui.SoloXformCheckBox->blockSignals(true);
|
||||
|
||||
if (m_Ember.m_Solo == combo->currentIndex())
|
||||
|
@ -110,13 +110,9 @@ void FractoriumEmberController<T>::SetupVariationsTree()
|
||||
const QSize hint0(170, 16);
|
||||
const QSize hint1(80, 16);
|
||||
const QSize hint2(20, 16);
|
||||
static vector<string> dc{ "m_ColorX" };
|
||||
static vector<string> assign{ "outPoint->m_X =", "outPoint->m_Y =", "outPoint->m_Z =",
|
||||
"outPoint->m_X=", "outPoint->m_Y=", "outPoint->m_Z=" };
|
||||
auto tree = m_Fractorium->ui.VariationsTree;
|
||||
tree->clear();
|
||||
tree->blockSignals(true);
|
||||
int iconSize_ = 20;
|
||||
|
||||
for (size_t i = 0; i < m_VariationList->Size(); i++)
|
||||
{
|
||||
@ -129,33 +125,8 @@ void FractoriumEmberController<T>::SetupVariationsTree()
|
||||
item->setSizeHint(0, hint0);
|
||||
item->setSizeHint(1, hint1);
|
||||
item->setSizeHint(2, hint2);
|
||||
QPixmap pixmap(iconSize_ * 3, iconSize_);
|
||||
auto mask = pixmap.createMaskFromColor(QColor("transparent"), Qt::MaskOutColor);
|
||||
pixmap.setMask(mask);
|
||||
QPainter paint(&pixmap);
|
||||
paint.fillRect(QRect(0, 0, iconSize_ * 3, iconSize_), QColor(0, 0, 0, 0));
|
||||
|
||||
if (var->VarType() == eVariationType::VARTYPE_REG)
|
||||
{
|
||||
if (SearchVar(var, assign, false))
|
||||
paint.fillRect(QRect(0, 0, iconSize_, iconSize_), QColor(255, 0, 0));
|
||||
}
|
||||
else if (var->VarType() == eVariationType::VARTYPE_PRE || var->VarType() == eVariationType::VARTYPE_POST)
|
||||
{
|
||||
if (var->AssignType() == eVariationAssignType::ASSIGNTYPE_SUM)
|
||||
paint.fillRect(QRect(0, 0, iconSize_, iconSize_), QColor(255, 0, 0));
|
||||
}
|
||||
|
||||
bool isDc = SearchVar(var, dc, false);
|
||||
|
||||
if (isDc)
|
||||
paint.fillRect(QRect(iconSize_, 0, iconSize_, iconSize_), QColor(0, 255, 0));
|
||||
|
||||
if (!var->StateOpenCLString().empty())
|
||||
paint.fillRect(QRect(iconSize_ * 2, 0, iconSize_, iconSize_), QColor(0, 0, 255));
|
||||
|
||||
QIcon qi(pixmap);
|
||||
item->setIcon(2, qi);
|
||||
auto qi = MakeVariationIcon(var);
|
||||
item->setIcon(0, qi);
|
||||
spinBox->setRange(fMin, fMax);
|
||||
spinBox->DoubleClick(true);
|
||||
spinBox->DoubleClickZero(1);
|
||||
@ -173,6 +144,7 @@ void FractoriumEmberController<T>::SetupVariationsTree()
|
||||
{
|
||||
if (!params[j].IsPrecalc())
|
||||
{
|
||||
auto def = params[j].Def();
|
||||
auto paramWidget = new VariationTreeWidgetItem(var->VariationId(), item);
|
||||
auto varSpinBox = new VariationTreeDoubleSpinBox(tree, paramWidget, parVar->VariationId(), params[j].Name());
|
||||
paramWidget->setText(0, params[j].Name().c_str());
|
||||
@ -181,8 +153,9 @@ void FractoriumEmberController<T>::SetupVariationsTree()
|
||||
varSpinBox->setRange(params[j].Min(), params[j].Max());
|
||||
varSpinBox->setValue(params[j].ParamVal());
|
||||
varSpinBox->DoubleClick(true);
|
||||
varSpinBox->DoubleClickZero(1);
|
||||
varSpinBox->DoubleClickNonZero(0);
|
||||
varSpinBox->DoubleClickZero(def != 0 ? 0 : 1);
|
||||
varSpinBox->DoubleClickLowVal(def);
|
||||
varSpinBox->DoubleClickNonZero(def);
|
||||
|
||||
if (params[j].Type() == eParamType::INTEGER || params[j].Type() == eParamType::INTEGER_NONZERO)
|
||||
{
|
||||
@ -387,6 +360,50 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
|
||||
m_Fractorium->OnTreeHeaderSectionClicked(m_Fractorium->m_VarSortMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an icon for the passed in variation which indicates the following:
|
||||
/// Red: position matters because it uses non-standard assigning vs. summing.
|
||||
/// Green: uses direct color.
|
||||
/// Blue: maintains internal state, mostly of engineering interest.
|
||||
/// </summary>
|
||||
/// <param name="text">The variation to create the icon for</param>
|
||||
/// <returns>The newly created icon</returns>
|
||||
template <typename T>
|
||||
QIcon FractoriumEmberController<T>::MakeVariationIcon(const Variation<T>* var)
|
||||
{
|
||||
const int iconSize = 20;
|
||||
static vector<string> dc{ "m_ColorX" };
|
||||
static vector<string> assign{ "outPoint->m_X =", "outPoint->m_Y =", "outPoint->m_Z =",
|
||||
"outPoint->m_X=", "outPoint->m_Y=", "outPoint->m_Z=" };
|
||||
QPixmap pixmap(iconSize * 3, iconSize);
|
||||
auto mask = pixmap.createMaskFromColor(QColor("transparent"), Qt::MaskOutColor);
|
||||
pixmap.setMask(mask);
|
||||
QPainter paint(&pixmap);
|
||||
paint.fillRect(QRect(0, 0, iconSize * 3, iconSize), QColor(0, 0, 0, 0));
|
||||
|
||||
if (var->VarType() == eVariationType::VARTYPE_REG)
|
||||
{
|
||||
if (SearchVar(var, assign, false))
|
||||
paint.fillRect(QRect(0, 0, iconSize, iconSize), QColor(255, 0, 0));
|
||||
}
|
||||
else if (var->VarType() == eVariationType::VARTYPE_PRE || var->VarType() == eVariationType::VARTYPE_POST)
|
||||
{
|
||||
if (var->AssignType() == eVariationAssignType::ASSIGNTYPE_SUM)
|
||||
paint.fillRect(QRect(0, 0, iconSize, iconSize), QColor(255, 0, 0));
|
||||
}
|
||||
|
||||
bool isDc = SearchVar(var, dc, false);
|
||||
|
||||
if (isDc)
|
||||
paint.fillRect(QRect(iconSize, 0, iconSize, iconSize), QColor(0, 255, 0));
|
||||
|
||||
if (!var->StateOpenCLString().empty())
|
||||
paint.fillRect(QRect(iconSize * 2, 0, iconSize, iconSize), QColor(0, 0, 255));
|
||||
|
||||
QIcon qi(pixmap);
|
||||
return qi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the sorting to be either by variation ID, or by weight.
|
||||
/// If sorting by variation ID, repeated clicks will alternate ascending or descending.
|
||||
|
@ -99,8 +99,8 @@ template <typename T>
|
||||
T GLEmberController<T>::CalcRotation()
|
||||
{
|
||||
const auto scrolledWorldCenter = ScrolledCenter(true);
|
||||
const T rotStart = NormalizeDeg180<T>((std::atan2(m_MouseDownWorldPos.y - scrolledWorldCenter.y, m_MouseDownWorldPos.x - scrolledWorldCenter.x) * RAD_2_DEG_T));
|
||||
const T rot = NormalizeDeg180<T>((std::atan2(m_MouseWorldPos.y - scrolledWorldCenter.y, m_MouseWorldPos.x - scrolledWorldCenter.x) * RAD_2_DEG_T));
|
||||
const T rotStart = NormalizeDeg360<T>((std::atan2(m_MouseDownWorldPos.y - scrolledWorldCenter.y, m_MouseDownWorldPos.x - scrolledWorldCenter.x) * RAD_2_DEG_T));
|
||||
const T rot = NormalizeDeg360<T>((std::atan2(m_MouseWorldPos.y - scrolledWorldCenter.y, m_MouseWorldPos.x - scrolledWorldCenter.x) * RAD_2_DEG_T));
|
||||
return rotStart - rot;
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1078,7 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
|
||||
{
|
||||
const T rot = CalcRotation();
|
||||
const T scale = CalcScale();
|
||||
ember->m_Rotate = NormalizeDeg180<T>(m_RotationDown + rot);
|
||||
ember->m_Rotate = NormalizeDeg360<T>(m_RotationDown + rot);
|
||||
m_Fractorium->SetRotation(ember->m_Rotate, true);
|
||||
m_Fractorium->SetScale(std::max(static_cast<T>(10), m_ScaleDown + scale));//Will restart the rendering process.
|
||||
}
|
||||
|
@ -841,6 +841,9 @@
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="AutoUniqueCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When resaving a file, use an auto generated unique name based on the first name supplied.</p><p>This allows you to keep snapshots of your changes instead of overwriting them with each save.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto Unique Filenames</string>
|
||||
</property>
|
||||
|
Loading…
Reference in New Issue
Block a user