Merged mfeemster/fractorium into master

This commit is contained in:
Michel Mastriani 2020-08-04 21:34:48 -03:00
commit e41fca7b7d
19 changed files with 312 additions and 107 deletions

View File

@ -6,7 +6,7 @@
<ProductVersion>3.7</ProductVersion> <ProductVersion>3.7</ProductVersion>
<ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid> <ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<OutputName>Fractorium_1.0.0.20</OutputName> <OutputName>Fractorium_1.0.0.21</OutputName>
<OutputType>Package</OutputType> <OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductVersion="1.0.0.20" ?> <?define ProductVersion="1.0.0.21" ?>
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?> <?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?> <?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?> <?define Manufacturer="Fractorium"?>
@ -13,7 +13,7 @@
<!-- <!--
Change this for every release. Change this for every release.
--> -->
<?define ProductCode="{A91C2097-2043-4A70-B3E9-F93426567195}"?> <?define ProductCode="{3BDFCE16-0944-4463-B475-82748BDC0AF1}"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)"> <Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package <Package
@ -168,19 +168,19 @@
<File Id="tbb.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\tbb.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" ReadOnly="yes"/> <File Id="tbb.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\tbb.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" ReadOnly="yes"/>
</Component> </Component>
<Component Id="msvcp140.dll" Guid="8f1ffde7-c1bd-45fb-8bc8-26dde552eafd"> <Component Id="msvcp140.dll" Guid="8f1ffde7-c1bd-45fb-8bc8-26dde552eafd">
<File Id="msvcp140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.25.28508\x64\Microsoft.VC142.CRT\msvcp140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="msvcp140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.26.28720\x64\Microsoft.VC142.CRT\msvcp140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component> </Component>
<Component Id="vcruntime140.dll" Guid="50c9bc27-c547-4a03-9f6c-cd416f449dd8"> <Component Id="vcruntime140.dll" Guid="50c9bc27-c547-4a03-9f6c-cd416f449dd8">
<File Id="vcruntime140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.25.28508\x64\Microsoft.VC142.CRT\vcruntime140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="vcruntime140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.26.28720\x64\Microsoft.VC142.CRT\vcruntime140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component> </Component>
<Component Id="vcruntime140_1.dll" Guid="a02507f8-326b-45b2-b734-e5091921559f"> <Component Id="vcruntime140_1.dll" Guid="a02507f8-326b-45b2-b734-e5091921559f">
<File Id="vcruntime140_1.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.25.28508\x64\Microsoft.VC142.CRT\vcruntime140_1.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="vcruntime140_1.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.26.28720\x64\Microsoft.VC142.CRT\vcruntime140_1.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component> </Component>
<Component Id="vccorlib140.dll" Guid="affe33e7-1e64-4bb0-a062-2b56f77459b4"> <Component Id="vccorlib140.dll" Guid="affe33e7-1e64-4bb0-a062-2b56f77459b4">
<File Id="vccorlib140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.25.28508\x64\Microsoft.VC142.CRT\vccorlib140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="vccorlib140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.26.28720\x64\Microsoft.VC142.CRT\vccorlib140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component> </Component>
<Component Id="concrt140.dll" Guid="7fb716a1-1b4f-42fb-89c7-4d216ebd6e2e"> <Component Id="concrt140.dll" Guid="7fb716a1-1b4f-42fb-89c7-4d216ebd6e2e">
<File Id="concrt140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.25.28508\x64\Microsoft.VC142.CRT\concrt140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="concrt140.dll" Source="$(var.DevEnvDir)..\..\VC\Redist\MSVC\14.26.28720\x64\Microsoft.VC142.CRT\concrt140.dll" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component> </Component>
<Component Id="flam3palettes.xml" Guid="d3adb0bb-14ef-4923-99d9-a5784b7ef04e"> <Component Id="flam3palettes.xml" Guid="d3adb0bb-14ef-4923-99d9-a5784b7ef04e">
<File Id="flam3palettes.xml" Source="$(var.SolutionDir)..\..\..\Data\flam3-palettes.xml" KeyPath="yes" Checksum="yes" ReadOnly="yes"/> <File Id="flam3palettes.xml" Source="$(var.SolutionDir)..\..\..\Data\flam3-palettes.xml" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>

Binary file not shown.

View File

@ -49,8 +49,8 @@
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 20 FILEVERSION 1, 0, 0, 21
PRODUCTVERSION 1, 0, 0, 20 PRODUCTVERSION 1, 0, 0, 21
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as animations with motion blur" VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
VALUE "FileVersion", "1, 0, 0, 20" VALUE "FileVersion", "1, 0, 0, 21"
VALUE "InternalName", "EmberAnimate.exe" VALUE "InternalName", "EmberAnimate.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3"
VALUE "OriginalFilename", "EmberAnimate.exe" VALUE "OriginalFilename", "EmberAnimate.exe"
VALUE "ProductName", "Ember Animate" VALUE "ProductName", "Ember Animate"
VALUE "ProductVersion", "1, 0, 0, 20" VALUE "ProductVersion", "1, 0, 0, 21"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -49,8 +49,8 @@
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 20 FILEVERSION 1, 0, 0, 21
PRODUCTVERSION 1, 0, 0, 20 PRODUCTVERSION 1, 0, 0, 21
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Manipulates fractal flame parameter files" VALUE "FileDescription", "Manipulates fractal flame parameter files"
VALUE "FileVersion", "1, 0, 0, 20" VALUE "FileVersion", "1, 0, 0, 21"
VALUE "InternalName", "EmberGenome.exe" VALUE "InternalName", "EmberGenome.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3"
VALUE "OriginalFilename", "EmberGenome.exe" VALUE "OriginalFilename", "EmberGenome.exe"
VALUE "ProductName", "Ember Genome" VALUE "ProductName", "Ember Genome"
VALUE "ProductVersion", "1, 0, 0, 20" VALUE "ProductVersion", "1, 0, 0, 21"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -49,8 +49,8 @@
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 20 FILEVERSION 1, 0, 0, 21
PRODUCTVERSION 1, 0, 0, 20 PRODUCTVERSION 1, 0, 0, 21
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as single images" VALUE "FileDescription", "Renders fractal flames as single images"
VALUE "FileVersion", "1, 0, 0, 20" VALUE "FileVersion", "1, 0, 0, 21"
VALUE "InternalName", "EmberRender.exe" VALUE "InternalName", "EmberRender.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3"
VALUE "OriginalFilename", "EmberRender.exe" VALUE "OriginalFilename", "EmberRender.exe"
VALUE "ProductName", "Ember Render" VALUE "ProductName", "Ember Render"
VALUE "ProductVersion", "1, 0, 0, 20" VALUE "ProductVersion", "1, 0, 0, 21"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -1,4 +1,4 @@
1.0.0.20 4/11/2020 1.0.0.21 4/11/2020
--Bug fixes --Bug fixes
-ETA time was wrong with incremental final renders after waiting for a period of time. -ETA time was wrong with incremental final renders after waiting for a period of time.
-Fix possible OpenCL bugs in cubic3D, cubicLattice_3D, dc_cube, falloff, falloff2, falloff3, waffle. -Fix possible OpenCL bugs in cubic3D, cubicLattice_3D, dc_cube, falloff, falloff2, falloff3, waffle.

View File

@ -496,6 +496,7 @@ uint Timing::m_ProcessorCount;
EXPORTPREPOSTREGVAR(Gnarly, T) \ EXPORTPREPOSTREGVAR(Gnarly, T) \
EXPORTPREPOSTREGVAR(Inkdrop, T) \ EXPORTPREPOSTREGVAR(Inkdrop, T) \
EXPORTPREPOSTREGVAR(HexModulus, T) \ EXPORTPREPOSTREGVAR(HexModulus, T) \
EXPORTPREPOSTREGVAR(Vignette, T) \
template EMBER_API class VariationList<T>; \ template EMBER_API class VariationList<T>; \
template EMBER_API class SpatialFilter<T>; \ template EMBER_API class SpatialFilter<T>; \
template EMBER_API class GaussianFilter<T>; \ template EMBER_API class GaussianFilter<T>; \

View File

@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
namespace EmberNs namespace EmberNs
{ {
#define EMBER_VERSION "1.0.0.20" #define EMBER_VERSION "1.0.0.21"
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h //#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 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. #define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.

View File

@ -433,6 +433,7 @@ enum class eVariationId : glm::uint
VAR_UNPOLAR , VAR_UNPOLAR ,
VAR_VIBRATION, VAR_VIBRATION,
VAR_VIBRATION2, VAR_VIBRATION2,
VAR_VIGNETTE,
VAR_VORON, VAR_VORON,
VAR_W , VAR_W ,
VAR_WAFFLE, VAR_WAFFLE,
@ -849,6 +850,7 @@ enum class eVariationId : glm::uint
VAR_PRE_UNPOLAR, VAR_PRE_UNPOLAR,
VAR_PRE_VIBRATION, VAR_PRE_VIBRATION,
VAR_PRE_VIBRATION2, VAR_PRE_VIBRATION2,
VAR_PRE_VIGNETTE,
VAR_PRE_VORON, VAR_PRE_VORON,
VAR_PRE_W, VAR_PRE_W,
VAR_PRE_WAFFLE, VAR_PRE_WAFFLE,
@ -1265,6 +1267,7 @@ enum class eVariationId : glm::uint
VAR_POST_UNPOLAR, VAR_POST_UNPOLAR,
VAR_POST_VIBRATION, VAR_POST_VIBRATION,
VAR_POST_VIBRATION2, VAR_POST_VIBRATION2,
VAR_POST_VIGNETTE,
VAR_POST_VORON, VAR_POST_VORON,
VAR_POST_W, VAR_POST_W,
VAR_POST_WAFFLE, VAR_POST_WAFFLE,

View File

@ -439,6 +439,7 @@ VariationList<T>::VariationList()
ADDPREPOSTREGVAR(Gnarly) ADDPREPOSTREGVAR(Gnarly)
ADDPREPOSTREGVAR(Inkdrop) ADDPREPOSTREGVAR(Inkdrop)
ADDPREPOSTREGVAR(HexModulus) ADDPREPOSTREGVAR(HexModulus)
ADDPREPOSTREGVAR(Vignette)
//ADDPREPOSTREGVAR(LinearXZ) //ADDPREPOSTREGVAR(LinearXZ)
//ADDPREPOSTREGVAR(LinearYZ) //ADDPREPOSTREGVAR(LinearYZ)
//DC are special. //DC are special.

View File

@ -2395,8 +2395,8 @@ public:
{ {
m_Ang = M_2PI / Zeps(m_Divisor); m_Ang = M_2PI / Zeps(m_Divisor);
T a = std::atan2((m_D < 0 ? -std::log(-m_D) : std::log(m_D)) * m_R, M_2PI); T a = std::atan2((m_D < 0 ? -std::log(-m_D) : std::log(m_D)) * m_R, M_2PI);
m_PrecalcC = std::cos(a) * m_R * std::cos(a) / m_Divisor; m_PrecalcC = std::cos(a) * m_R * std::cos(a) / Zeps(m_Divisor);
m_PrecalcD = std::cos(a) * m_R * std::sin(a) / m_Divisor; m_PrecalcD = std::cos(a) * m_R * std::sin(a) / Zeps(m_Divisor);
m_HalfC = m_PrecalcC / 2; m_HalfC = m_PrecalcC / 2;
m_HalfD = m_PrecalcD / 2; m_HalfD = m_PrecalcD / 2;
m_Coeff = m_PrecalcD == 0 ? 0 : T(-0.095) * m_Spread / m_PrecalcD; m_Coeff = m_PrecalcD == 0 ? 0 : T(-0.095) * m_Spread / m_PrecalcD;
@ -7564,6 +7564,199 @@ private:
T m_Yfact001;//Precalc. T m_Yfact001;//Precalc.
}; };
/// <summary>
/// vignette by Bezo97.
/// </summary>
template <typename T>
class VignetteVariation : public ParametricVariation<T>
{
public:
VignetteVariation(T weight = 1.0) : ParametricVariation<T>("vignette", eVariationId::VAR_VIGNETTE, weight)
{
Init();
}
PARVARCOPY(VignetteVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T px = helper.In.x;
T py = helper.In.y;
T dist = std::sqrt((px - m_Posx) * (px - m_Posx) + (py - m_Posy) * (py - m_Posy));
helper.Out.z = DefaultZ(helper);
if (dist < m_InnerabsPrecalc)
{
//middle part
if (m_Innerradius < 0.0)
{
helper.Out.x = 0;
helper.Out.y = 0;
return;
}
helper.Out.x = px * m_Weight;
helper.Out.y = py * m_Weight;
return;
}
//map to 0-1
dist = (dist - m_InnerabsPrecalc) / m_FadeabsPrecalc;
T fade = T(1.0) - std::pow(rand.Frand01<T>(), m_PowerhelperPrecalc);
T blur_r = m_Blur * std::pow(dist * rand.Frand01<T>(), T(2.0));
T blur_a = rand.Frand01<T>() * M_2PI;
if (m_Faderadius > 0)
{
//vignette
if (fade < dist)
{
px = 0;
py = 0;
}
else
{
px += blur_r * std::cos(blur_a);
py += blur_r * std::sin(blur_a);
}
}
else
{
//inverse vignette
if (1 - fade > dist)
{
px = 0;
py = 0;
}
else
{
px += blur_r * std::cos(blur_a);
py += blur_r * std::sin(blur_a);
}
}
helper.Out.x = px * m_Weight;
helper.Out.y = py * m_Weight;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string weight = WeightDefineString();
string posx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string posy = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string innerradius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string faderadius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string blur = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string innerabsprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string fadeabsprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string powerhelperprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t px = vIn.x;\n"
<< "\t\treal_t py = vIn.y;\n"
<< "\t\treal_t dist = sqrt((px - " << posx << ") * (px - " << posx << ") + (py - " << posy << ") * (py - " << posy << "));\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\n"
<< "\t\tif (dist < " << innerabsprecalc << ")\n"
<< "\t\t{\n"
<< "\t\t\tif (" << innerradius << " < (real_t)(0.0))\n"
<< "\t\t\t{\n"
<< "\t\t\t\tvOut.x = (real_t)(0.0);\n"
<< "\t\t\t\tvOut.y = (real_t)(0.0);\n"
<< "\t\t\t}\n"
<< "\t\t\telse\n"
<< "\t\t\t{\n"
<< "\t\t\t\tvOut.x = px * " << weight << ";\n"
<< "\t\t\t\tvOut.y = py * " << weight << ";\n"
<< "\t\t\t}\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tdist = (dist - " << innerabsprecalc << ") / " << fadeabsprecalc << ";\n"
<< "\n"
<< "\t\t\treal_t fade = (real_t)(1.0) - pow(MwcNext01(mwc), " << powerhelperprecalc << ");\n"
<< "\t\t\treal_t blur_r = " << blur << " * pow(dist * MwcNext01(mwc), (real_t)(2.0));\n"
<< "\t\t\treal_t blur_a = MwcNext01(mwc) * M_2PI;\n"
<< "\n"
<< "\t\t\tif (" << faderadius << " > 0.0)\n"
<< "\t\t\t{\n"
<< "\t\t\t\tif (fade < dist)\n"
<< "\t\t\t\t{\n"
<< "\t\t\t\t\tpx = (real_t)(0.0);\n"
<< "\t\t\t\t\tpy = (real_t)(0.0);\n"
<< "\t\t\t\t}\n"
<< "\t\t\t\telse\n"
<< "\t\t\t\t{\n"
<< "\t\t\t\t\tpx += blur_r * cos(blur_a);\n"
<< "\t\t\t\t\tpy += blur_r * sin(blur_a);\n"
<< "\t\t\t\t}\n"
<< "\t\t\t}\n"
<< "\t\t\telse\n"
<< "\t\t\t{\n"
<< "\t\t\t\tif (1 - fade > dist)\n"
<< "\t\t\t\t{\n"
<< "\t\t\t\t\tpx = (real_t)(0.0);\n"
<< "\t\t\t\t\tpy = (real_t)(0.0);\n"
<< "\t\t\t\t}\n"
<< "\t\t\t\telse\n"
<< "\t\t\t\t{\n"
<< "\t\t\t\t\tpx += blur_r * cos(blur_a);\n"
<< "\t\t\t\t\tpy += blur_r * sin(blur_a);\n"
<< "\t\t\t\t}\n"
<< "\t\t\t}\n"
<< "\n"
<< "\t\t\tvOut.x = px * " << weight << ";\n"
<< "\t\t\tvOut.y = py * " << weight << ";\n"
<< "\t\t}\n"
<< "\t}\n";
return ss.str();
}
virtual void Precalc() override
{
m_InnerabsPrecalc = std::abs(m_Innerradius);
m_FadeabsPrecalc = std::abs(m_Faderadius);
m_PowerhelperPrecalc = T(1.0) / std::abs(m_Power);
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Zeps" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Posx, prefix + "vignette_posx"));
m_Params.push_back(ParamWithName<T>(&m_Posy, prefix + "vignette_posy"));
m_Params.push_back(ParamWithName<T>(&m_Innerradius, prefix + "vignette_inner_radius", T(0.5)));
m_Params.push_back(ParamWithName<T>(&m_Faderadius, prefix + "vignette_fade_radius", T(0.5), eParamType::REAL_NONZERO));
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "vignette_power", T(4.0), eParamType::REAL_NONZERO));
m_Params.push_back(ParamWithName<T>(&m_Blur, prefix + "vignette_blur", T(1.0)));
m_Params.push_back(ParamWithName<T>(true, &m_InnerabsPrecalc, prefix + "vignette_inner_abs_precalc"));//Precalc.
m_Params.push_back(ParamWithName<T>(true, &m_FadeabsPrecalc, prefix + "vignette_fade_abs_precalc"));
m_Params.push_back(ParamWithName<T>(true, &m_PowerhelperPrecalc, prefix + "vignette_power_helper_precalc"));
}
private:
T m_Posx;
T m_Posy;
T m_Innerradius;
T m_Faderadius;
T m_Power;
T m_Blur;
T m_InnerabsPrecalc;//Precalc.
T m_FadeabsPrecalc;
T m_PowerhelperPrecalc;
};
MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D) MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D)
MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B) MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B)
MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN) MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN)
@ -7634,4 +7827,5 @@ MAKEPREPOSTPARVAR(Waves23, waves23, WAVES23)
MAKEPREPOSTPARVAR(Waves42, waves42, WAVES42) MAKEPREPOSTPARVAR(Waves42, waves42, WAVES42)
MAKEPREPOSTPARVAR(Waves3, waves3, WAVES3) MAKEPREPOSTPARVAR(Waves3, waves3, WAVES3)
MAKEPREPOSTPARVAR(Waves4, waves4, WAVES4) MAKEPREPOSTPARVAR(Waves4, waves4, WAVES4)
MAKEPREPOSTPARVAR(Vignette, vignette, VIGNETTE)
} }

View File

@ -1198,7 +1198,15 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
std::string periterweights; std::string periterweights;
if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "base_weight")) if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "base_weight"))
if (ParseAndAssignContent(baseWeightChildNode, "name", "base_weight", weight)) { xf.m_Weight = weight; } {
if (ParseAndAssignContent(baseWeightChildNode, "name", "base_weight", weight))
xf.m_Weight = weight;
}
else if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "Base weight"))
{
if (ParseAndAssignContent(baseWeightChildNode, "name", "Base weight", weight))
xf.m_Weight = weight;
}
if (auto periterweightsChildNode = GetChildNode(weightsChildNode, "per_iterator_weights")) if (auto periterweightsChildNode = GetChildNode(weightsChildNode, "per_iterator_weights"))
{ {

View File

@ -58,7 +58,7 @@
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Fractorium 1.0.0.20&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;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.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Fractorium 1.0.0.21&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;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.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>

View File

@ -382,8 +382,8 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
{ {
auto combo = ui.CurrentXformCombo; auto combo = ui.CurrentXformCombo;
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
int times = 3; const int times = 3;
int ftimes = 2; const int ftimes = 2;
if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F32) if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F32)
{ {
@ -391,7 +391,7 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
if (fcount >= ftimes) if (fcount >= ftimes)
{ {
int val = ke->key() - (int)Qt::Key_F1; const int val = ke->key() - (int)Qt::Key_F1;
if (val < combo->count()) if (val < combo->count())
combo->setCurrentIndex(val); combo->setCurrentIndex(val);
@ -417,10 +417,10 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
} }
else if (o == this) else if (o == this)
{ {
auto focusedctrlEdit = dynamic_cast<QLineEdit*>(this->focusWidget()); const auto focusedctrlEdit = dynamic_cast<QLineEdit*>(this->focusWidget());
auto focusedctrlSpin = dynamic_cast<QSpinBox*>(this->focusWidget()); const auto focusedctrlSpin = dynamic_cast<QSpinBox*>(this->focusWidget());
auto focusedctrlDblSpin = dynamic_cast<QDoubleSpinBox*>(this->focusWidget()); const auto focusedctrlDblSpin = dynamic_cast<QDoubleSpinBox*>(this->focusWidget());
auto focusedctrlCombo = dynamic_cast<QComboBox*>(this->focusWidget()); const auto focusedctrlCombo = dynamic_cast<QComboBox*>(this->focusWidget());
if (!focusedctrlEdit && if (!focusedctrlEdit &&
!focusedctrlSpin && !focusedctrlSpin &&
@ -434,11 +434,11 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
double zoom = 1; double zoom = 1;
double rot = 1; double rot = 1;
double grow = 0.01; double grow = 0.01;
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); const bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); const bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
bool pre = true; bool pre = true;
if (auto r = m_Controller->Renderer()) if (const auto r = m_Controller->Renderer())
{ {
hdist = std::abs(r->UpperRightX() - r->LowerLeftX()) * 0.01 * m_Controller->AffineScaleLockedToCurrent(); hdist = std::abs(r->UpperRightX() - r->LowerLeftX()) * 0.01 * m_Controller->AffineScaleLockedToCurrent();
vdist = std::abs(r->UpperRightY() - r->LowerLeftY()) * 0.01 * m_Controller->AffineScaleLockedToCurrent(); vdist = std::abs(r->UpperRightY() - r->LowerLeftY()) * 0.01 * m_Controller->AffineScaleLockedToCurrent();

View File

@ -8745,7 +8745,7 @@
<string>Pre</string> <string>Pre</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Show/Hide Pre Affines</string> <string>Show/Hide Pre Affines (P)</string>
</property> </property>
</action> </action>
<action name="ActionDrawAllPreAffines"> <action name="ActionDrawAllPreAffines">
@ -8756,7 +8756,7 @@
<string>All</string> <string>All</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Show All Pre Affines</string> <string>Show All Pre Affines (L)</string>
</property> </property>
</action> </action>
<action name="ActionDrawPostAffines"> <action name="ActionDrawPostAffines">
@ -8767,7 +8767,7 @@
<string>Post</string> <string>Post</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Show/Hide Post Affines</string> <string>Show/Hide Post Affines (Shift + P)</string>
</property> </property>
</action> </action>
<action name="ActionDrawAllPostAffines"> <action name="ActionDrawAllPostAffines">
@ -8778,7 +8778,7 @@
<string>All</string> <string>All</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Show All Post Affines</string> <string>Show All Post Affines (Shift + L)</string>
</property> </property>
</action> </action>
<action name="ActionCreateReferenceFile"> <action name="ActionCreateReferenceFile">

View File

@ -7,10 +7,11 @@
void Fractorium::InitLibraryUI() void Fractorium::InitLibraryUI()
{ {
ui.LibraryTree->SetMainWindow(this); ui.LibraryTree->SetMainWindow(this);
connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection); //Making the TreeItemChanged() events use a direct connection is absolutely critical.
connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::DirectConnection);
connect(ui.LibraryTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection);
connect(ui.LibraryTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection);
connect(ui.SequenceTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnSequenceTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.SequenceTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnSequenceTreeItemChanged(QTreeWidgetItem*, int)), Qt::DirectConnection);
connect(ui.SequenceStartPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStartPreviewsButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceStartPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStartPreviewsButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceStopPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStopPreviewsButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceStopPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStopPreviewsButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAllButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAllButtonClicked(bool)), Qt::QueuedConnection);
@ -68,7 +69,7 @@ void Fractorium::InitLibraryUI()
/// <param name="index">The 0-based index of the item in the library tree to select</param> /// <param name="index">The 0-based index of the item in the library tree to select</param>
void Fractorium::SelectLibraryItem(size_t index) void Fractorium::SelectLibraryItem(size_t index)
{ {
if (auto top = ui.LibraryTree->topLevelItem(0)) if (const auto top = ui.LibraryTree->topLevelItem(0))
{ {
for (int i = 0; i < top->childCount(); i++) for (int i = 0; i < top->childCount(); i++)
{ {
@ -89,10 +90,10 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex()
{ {
int index = 0; int index = 0;
QTreeWidgetItem* item = nullptr; QTreeWidgetItem* item = nullptr;
auto tree = ui.LibraryTree; const auto tree = ui.LibraryTree;
vector<pair<size_t, QTreeWidgetItem*>> v; vector<pair<size_t, QTreeWidgetItem*>> v;
if (auto top = tree->topLevelItem(0)) if (const auto top = tree->topLevelItem(0))
{ {
for (int i = 0; i < top->childCount(); i++)//Iterate through all of the children, which will represent the open embers. for (int i = 0; i < top->childCount(); i++)//Iterate through all of the children, which will represent the open embers.
{ {
@ -117,7 +118,7 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex()
/// <param name="h">The height of the bitmap</param> /// <param name="h">The height of the bitmap</param>
void Fractorium::SetLibraryTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h) void Fractorium::SetLibraryTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h)
{ {
m_PreviewVec.resize(w * h * 4); m_PreviewVec.resize(size_t(w) * size_t(h) * 4);
Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency()); Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency());
item->SetImage(m_PreviewVec, w, h); item->SetImage(m_PreviewVec, w, h);
} }
@ -131,9 +132,9 @@ template <typename T>
void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update) void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update)
{ {
auto it = m_EmberFile.m_Embers.begin(); auto it = m_EmberFile.m_Embers.begin();
auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
if (auto top = tree->topLevelItem(0)) if (const auto top = tree->topLevelItem(0))
{ {
for (int i = 0; i < top->childCount() && it != m_EmberFile.m_Embers.end(); ++i, ++it)//Iterate through all of the children, which will represent the open embers. for (int i = 0; i < top->childCount() && it != m_EmberFile.m_Embers.end(); ++i, ++it)//Iterate through all of the children, which will represent the open embers.
{ {
@ -166,11 +167,10 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
{ {
uint size = 64; uint size = 64;
uint i = 0; uint i = 0;
auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
vector<byte> v(size * size * 4); vector<byte> v(size * size * 4);
StopAllPreviewRenderers(); StopAllPreviewRenderers();
tree->clear(); tree->clear();
QCoreApplication::processEvents();
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_EmberFile.m_Filename); QFileInfo info(m_EmberFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -205,13 +205,13 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
template <typename T> template <typename T>
void FractoriumEmberController<T>::UpdateLibraryTree() void FractoriumEmberController<T>::UpdateLibraryTree()
{ {
uint size = 64; const uint size = 64;
vector<byte> v(size * size * 4); vector<byte> v(size * size * 4);
auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
if (auto top = tree->topLevelItem(0)) if (auto top = tree->topLevelItem(0))
{ {
int origChildCount = top->childCount(); const int origChildCount = top->childCount();
int i = origChildCount; int i = origChildCount;
for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it) for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it)
@ -249,25 +249,24 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
{ {
try try
{ {
auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item)) if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item))
{ {
if (!emberItem->isSelected())//Checking/unchecking other items shouldn't perform the processing below. auto oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
auto newName = emberItem->text(0).toStdString();
//Checking/unchecking other items shouldn't perform the processing below.
//If nothing changed, nothing to do.
if (!emberItem->isSelected() && newName == oldName)
return; return;
if (emberItem->text(0).isEmpty())//Prevent empty string. if (newName.empty())//Prevent empty string.
{ {
emberItem->UpdateEditText(); emberItem->UpdateEditText();
return; return;
} }
string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
string newName = emberItem->text(0).toStdString();
if (oldName == newName)//If nothing changed, nothing to do.
return;
emberItem->UpdateEmberName();//Copy edit text to the ember's name variable. emberItem->UpdateEmberName();//Copy edit text to the ember's name variable.
m_EmberFile.MakeNamesUnique();//Ensure all names remain unique. m_EmberFile.MakeNamesUnique();//Ensure all names remain unique.
SyncLibrary(eLibraryUpdate::NAME);//Copy all ember names to the tree items since some might have changed to be made unique. SyncLibrary(eLibraryUpdate::NAME);//Copy all ember names to the tree items since some might have changed to be made unique.
@ -281,7 +280,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
} }
else if (auto parentItem = dynamic_cast<QTreeWidgetItem*>(item)) else if (auto parentItem = dynamic_cast<QTreeWidgetItem*>(item))
{ {
QString text = parentItem->text(0); auto text = parentItem->text(0);
if (text != "") if (text != "")
{ {
@ -298,7 +297,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col) void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col)
{ {
if (ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty. if (item && ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty.
m_Controller->EmberTreeItemChanged(item, col); m_Controller->EmberTreeItemChanged(item, col);
} }
@ -334,9 +333,9 @@ template <typename T>
void FractoriumEmberController<T>::MoveLibraryItems(const QModelIndexList& items, int destRow) void FractoriumEmberController<T>::MoveLibraryItems(const QModelIndexList& items, int destRow)
{ {
int i = 0; int i = 0;
auto startRow = items[0].row(); const auto startRow = items[0].row();
auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
auto top = tree->topLevelItem(0); const auto top = tree->topLevelItem(0);
list<string> names; list<string> names;
for (auto& item : items) for (auto& item : items)
@ -344,7 +343,7 @@ void FractoriumEmberController<T>::MoveLibraryItems(const QModelIndexList& items
names.push_back(temp->m_Name); names.push_back(temp->m_Name);
auto b = m_EmberFile.m_Embers.begin(); auto b = m_EmberFile.m_Embers.begin();
auto result = Gather(b, m_EmberFile.m_Embers.end(), Advance(b, destRow), [&](const Ember<T>& ember) const auto result = Gather(b, m_EmberFile.m_Embers.end(), Advance(b, destRow), [&](const Ember<T>& ember)
{ {
auto position = std::find(names.begin(), names.end(), ember.m_Name); auto position = std::find(names.begin(), names.end(), ember.m_Name);
@ -387,7 +386,7 @@ void FractoriumEmberController<T>::Delete(const vector<pair<size_t, QTreeWidgetI
} }
//Select the next item in the tree closest to the last one that was deleted. //Select the next item in the tree closest to the last one that was deleted.
if (auto top = m_Fractorium->ui.LibraryTree->topLevelItem(0)) if (const auto top = m_Fractorium->ui.LibraryTree->topLevelItem(0))
{ {
last = std::min<uint>(top->childCount() - 1, last); last = std::min<uint>(top->childCount() - 1, last);
@ -421,9 +420,9 @@ void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreview
if (start == UINT_MAX && end == UINT_MAX) if (start == UINT_MAX && end == UINT_MAX)
{ {
if (auto top = tree->topLevelItem(0)) if (const auto top = tree->topLevelItem(0))
{ {
int childCount = top->childCount(); const auto childCount = top->childCount();
vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4); vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4);
for (int i = 0; i < childCount; i++) for (int i = 0; i < childCount; i++)
@ -469,13 +468,12 @@ void FractoriumEmberController<T>::StopAllPreviewRenderers()
template <typename T> template <typename T>
void FractoriumEmberController<T>::FillSequenceTree() void FractoriumEmberController<T>::FillSequenceTree()
{ {
uint size = 64; const uint size = 64;
uint i = 0; uint i = 0;
auto tree = m_Fractorium->ui.SequenceTree; const auto tree = m_Fractorium->ui.SequenceTree;
vector<byte> v(size * size * 4); vector<byte> v(size * size * 4);
m_SequencePreviewRenderer->Stop(); m_SequencePreviewRenderer->Stop();
tree->clear(); tree->clear();
QCoreApplication::processEvents();//Having to flush events is usually a sign of poor design. However, in this case, it's critical to have this here, else rapid button clicks will crash.
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_SequenceFile.m_Filename); QFileInfo info(m_SequenceFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -512,7 +510,7 @@ void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item
{ {
if (item == m_Fractorium->ui.SequenceTree->topLevelItem(0)) if (item == m_Fractorium->ui.SequenceTree->topLevelItem(0))
{ {
QString text = item->text(0); auto text = item->text(0);
if (text != "") if (text != "")
m_SequenceFile.m_Filename = text; m_SequenceFile.m_Filename = text;
@ -521,7 +519,7 @@ void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item
void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col) void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col)
{ {
if (ui.SequenceTree->topLevelItemCount()) if (item && ui.SequenceTree->topLevelItemCount())
m_Controller->SequenceTreeItemChanged(item, col); m_Controller->SequenceTreeItemChanged(item, col);
} }
@ -549,9 +547,9 @@ void Fractorium::OnSequenceStopPreviewsButtonClicked(bool checked) { m_Controlle
/// </summary> /// </summary>
void Fractorium::SyncFileCountToSequenceCount() void Fractorium::SyncFileCountToSequenceCount()
{ {
if (auto top = ui.LibraryTree->topLevelItem(0)) if (const auto top = ui.LibraryTree->topLevelItem(0))
{ {
int count = top->childCount() - 1; const int count = top->childCount() - 1;
ui.LibraryTree->headerItem()->setText(0, "Current Flame File (" + QString::number(top->childCount()) + ")"); ui.LibraryTree->headerItem()->setText(0, "Current Flame File (" + QString::number(top->childCount()) + ")");
ui.SequenceStartFlameSpinBox->setMinimum(0); ui.SequenceStartFlameSpinBox->setMinimum(0);
ui.SequenceStartFlameSpinBox->setMaximum(count); ui.SequenceStartFlameSpinBox->setMaximum(count);
@ -581,33 +579,33 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
auto& ui = m_Fractorium->ui; auto& ui = m_Fractorium->ui;
auto s = m_Fractorium->m_Settings; auto s = m_Fractorium->m_Settings;
//Bools for determining whether to use hard coded vs. random values. //Bools for determining whether to use hard coded vs. random values.
bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked(); const bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked();
bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked(); const bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked();
bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked(); const bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked();
bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked(); const bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked();
bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked(); const bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked();
//The direction to rotate the loops. //The direction to rotate the loops.
bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked(); const bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked();
bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked(); const bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked();
//Whether to stagger, default is 1 which means no stagger. //Whether to stagger, default is 1 which means no stagger.
double stagger = ui.SequenceStaggerSpinBox->value(); const double stagger = ui.SequenceStaggerSpinBox->value();
double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value(); const double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value();
//Rotations on keyframes. //Rotations on keyframes.
double rots = ui.SequenceRotationsSpinBox->value(); const double rots = ui.SequenceRotationsSpinBox->value();
double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value(); const double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value();
//Number of frames it takes to rotate a keyframe. //Number of frames it takes to rotate a keyframe.
int framesPerRot = ui.SequenceFramesPerRotSpinBox->value(); const int framesPerRot = ui.SequenceFramesPerRotSpinBox->value();
int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value(); const int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value();
//Number of frames it takes to interpolate. //Number of frames it takes to interpolate.
int framesBlend = ui.SequenceBlendFramesSpinBox->value(); const int framesBlend = ui.SequenceBlendFramesSpinBox->value();
int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value(); const int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value();
//Number of rotations performed during interpolation. //Number of rotations performed during interpolation.
int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value(); const int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value();
int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value(); const int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value();
size_t start = ui.SequenceStartFlameSpinBox->value(); const size_t start = ui.SequenceStartFlameSpinBox->value();
size_t stop = ui.SequenceStopFlameSpinBox->value(); const size_t stop = ui.SequenceStopFlameSpinBox->value();
size_t startCount = ui.SequenceStartCountSpinBox->value(); const size_t startCount = ui.SequenceStartCountSpinBox->value();
size_t keyFrames = (stop - start) + 1; const size_t keyFrames = (stop - start) + 1;
size_t frameCount = 0; size_t frameCount = 0;
double frames = 0; double frames = 0;
vector<pair<size_t, size_t>> devices;//Dummy. vector<pair<size_t, size_t>> devices;//Dummy.
@ -674,18 +672,18 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
double blend; double blend;
size_t frame; size_t frame;
Ember<T> embers[2];//Spin needs contiguous array below, and this will also get modified, so a copy is needed to avoid modifying the embers in the original file. Ember<T> embers[2];//Spin needs contiguous array below, and this will also get modified, so a copy is needed to avoid modifying the embers in the original file.
auto padding = streamsize(std::log10(frames)) + 1; const auto padding = streamsize(std::log10(frames)) + 1;
auto it = Advance(m_EmberFile.m_Embers.begin(), start); auto it = Advance(m_EmberFile.m_Embers.begin(), start);
for (size_t i = start; i <= stop && it != m_EmberFile.m_Embers.end(); i++, ++it) for (size_t i = start; i <= stop && it != m_EmberFile.m_Embers.end(); i++, ++it)
{ {
double rotations = randRot ? m_Rand.Frand<double>(rots, rotsMax) : rots; const auto rotations = randRot ? m_Rand.Frand<double>(rots, rotsMax) : rots;
embers[0] = *it; embers[0] = *it;
if (rotations > 0) if (rotations > 0)
{ {
double rotFrames = randFramesRot ? m_Rand.Frand<double>(framesPerRot, framesPerRotMax) : framesPerRot; const auto rotFrames = randFramesRot ? m_Rand.Frand<double>(framesPerRot, framesPerRotMax) : framesPerRot;
size_t roundFrames = size_t(std::round(rotFrames * rotations)); const auto roundFrames = size_t(std::round(rotFrames * rotations));
for (frame = 0; frame < roundFrames; frame++) for (frame = 0; frame < roundFrames; frame++)
{ {
@ -711,9 +709,9 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
auto it2 = it;//Need a quick temporary to avoid modifying it which is used in the loop. auto it2 = it;//Need a quick temporary to avoid modifying it which is used in the loop.
embers[1] = *(++it2);//Get the next ember to be used with blending below. embers[1] = *(++it2);//Get the next ember to be used with blending below.
size_t blendFrames = randBlend ? m_Rand.Frand<double>(framesBlend, framesBlendMax) : framesBlend; const auto blendFrames = randBlend ? m_Rand.Frand<double>(framesBlend, framesBlendMax) : framesBlend;
double d = randBlendRot ? m_Rand.Frand<double>(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend); const auto d = randBlendRot ? m_Rand.Frand<double>(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend);
size_t rpb = size_t(std::round(d)); const auto rpb = size_t(std::round(d));
if (randStagger) if (randStagger)
tools.Stagger(m_Rand.Frand<double>(stagger, staggerMax)); tools.Stagger(m_Rand.Frand<double>(stagger, staggerMax));
@ -722,7 +720,7 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
{ {
//if (frame == 43) //if (frame == 43)
// cout << frame << endl; // cout << frame << endl;
bool seqFlag = frame == 0 || (frame == blendFrames - 1); const auto seqFlag = frame == 0 || (frame == blendFrames - 1);
blend = frame / double(blendFrames); blend = frame / double(blendFrames);
result.Clear(); result.Clear();
tools.SpinInter(&embers[0], nullptr, result, startCount + frameCount++, seqFlag, blend, rpb, loopsBlendCw); tools.SpinInter(&embers[0], nullptr, result, startCount + frameCount++, seqFlag, blend, rpb, loopsBlendCw);