mirror of
				https://bitbucket.org/mfeemster/fractorium.git
				synced 2025-10-28 16:00:24 -04:00 
			
		
		
		
	Merged mfeemster/fractorium into master
This commit is contained in:
		| @ -6,7 +6,7 @@ | ||||
|     <ProductVersion>3.7</ProductVersion> | ||||
|     <ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid> | ||||
|     <SchemaVersion>2.0</SchemaVersion> | ||||
|     <OutputName>Fractorium_1.0.0.20</OutputName> | ||||
|     <OutputName>Fractorium_1.0.0.21</OutputName> | ||||
|     <OutputType>Package</OutputType> | ||||
|     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> | ||||
|     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <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 UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?> | ||||
| 	<?define Manufacturer="Fractorium"?> | ||||
| @ -13,7 +13,7 @@ | ||||
| 	<!-- | ||||
| 	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)"> | ||||
| 		<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"/> | ||||
| 			</Component> | ||||
| 			<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 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 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 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 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 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"/> | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -49,8 +49,8 @@ | ||||
| 	// | ||||
|  | ||||
| 	VS_VERSION_INFO VERSIONINFO | ||||
| 	FILEVERSION 1, 0, 0, 20 | ||||
| 	PRODUCTVERSION 1, 0, 0, 20 | ||||
| 	FILEVERSION 1, 0, 0, 21 | ||||
| 	PRODUCTVERSION 1, 0, 0, 21 | ||||
| 	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", "1, 0, 0, 20" | ||||
| 	VALUE "FileVersion", "1, 0, 0, 21" | ||||
| 	VALUE "InternalName", "EmberAnimate.exe" | ||||
| 	VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" | ||||
| 	VALUE "OriginalFilename", "EmberAnimate.exe" | ||||
| 	VALUE "ProductName", "Ember Animate" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 20" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 21" | ||||
| 	END | ||||
| 	END | ||||
| 	BLOCK "VarFileInfo" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -49,8 +49,8 @@ | ||||
| 	// | ||||
|  | ||||
| 	VS_VERSION_INFO VERSIONINFO | ||||
| 	FILEVERSION 1, 0, 0, 20 | ||||
| 	PRODUCTVERSION 1, 0, 0, 20 | ||||
| 	FILEVERSION 1, 0, 0, 21 | ||||
| 	PRODUCTVERSION 1, 0, 0, 21 | ||||
| 	FILEFLAGSMASK 0x3fL | ||||
| 	#ifdef _DEBUG | ||||
| 		FILEFLAGS 0x1L | ||||
| @ -67,12 +67,12 @@ | ||||
| 	BEGIN | ||||
| 	VALUE "CompanyName", "Open Source" | ||||
| 	VALUE "FileDescription", "Manipulates fractal flame parameter files" | ||||
| 	VALUE "FileVersion", "1, 0, 0, 20" | ||||
| 	VALUE "FileVersion", "1, 0, 0, 21" | ||||
| 	VALUE "InternalName", "EmberGenome.exe" | ||||
| 	VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" | ||||
| 	VALUE "OriginalFilename", "EmberGenome.exe" | ||||
| 	VALUE "ProductName", "Ember Genome" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 20" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 21" | ||||
| 	END | ||||
| 	END | ||||
| 	BLOCK "VarFileInfo" | ||||
|  | ||||
| @ -49,8 +49,8 @@ | ||||
| 	// | ||||
|  | ||||
| 	VS_VERSION_INFO VERSIONINFO | ||||
| 	FILEVERSION 1, 0, 0, 20 | ||||
| 	PRODUCTVERSION 1, 0, 0, 20 | ||||
| 	FILEVERSION 1, 0, 0, 21 | ||||
| 	PRODUCTVERSION 1, 0, 0, 21 | ||||
| 	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", "1, 0, 0, 20" | ||||
| 	VALUE "FileVersion", "1, 0, 0, 21" | ||||
| 	VALUE "InternalName", "EmberRender.exe" | ||||
| 	VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" | ||||
| 	VALUE "OriginalFilename", "EmberRender.exe" | ||||
| 	VALUE "ProductName", "Ember Render" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 20" | ||||
| 	VALUE "ProductVersion", "1, 0, 0, 21" | ||||
| 	END | ||||
| 	END | ||||
| 	BLOCK "VarFileInfo" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -1,4 +1,4 @@ | ||||
| 1.0.0.20 4/11/2020 | ||||
| 1.0.0.21 4/11/2020 | ||||
| --Bug fixes | ||||
|  -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. | ||||
|  | ||||
| @ -496,6 +496,7 @@ uint Timing::m_ProcessorCount; | ||||
| 	EXPORTPREPOSTREGVAR(Gnarly, T) \ | ||||
| 	EXPORTPREPOSTREGVAR(Inkdrop, T) \ | ||||
| 	EXPORTPREPOSTREGVAR(HexModulus, T) \ | ||||
| 	EXPORTPREPOSTREGVAR(Vignette, 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 "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 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. | ||||
|  | ||||
| @ -433,6 +433,7 @@ enum class eVariationId : glm::uint | ||||
| 	VAR_UNPOLAR		, | ||||
| 	VAR_VIBRATION, | ||||
| 	VAR_VIBRATION2, | ||||
| 	VAR_VIGNETTE, | ||||
| 	VAR_VORON, | ||||
| 	VAR_W			, | ||||
| 	VAR_WAFFLE, | ||||
| @ -849,6 +850,7 @@ enum class eVariationId : glm::uint | ||||
| 	VAR_PRE_UNPOLAR, | ||||
| 	VAR_PRE_VIBRATION, | ||||
| 	VAR_PRE_VIBRATION2, | ||||
| 	VAR_PRE_VIGNETTE, | ||||
| 	VAR_PRE_VORON, | ||||
| 	VAR_PRE_W, | ||||
| 	VAR_PRE_WAFFLE, | ||||
| @ -1265,6 +1267,7 @@ enum class eVariationId : glm::uint | ||||
| 	VAR_POST_UNPOLAR, | ||||
| 	VAR_POST_VIBRATION, | ||||
| 	VAR_POST_VIBRATION2, | ||||
| 	VAR_POST_VIGNETTE, | ||||
| 	VAR_POST_VORON, | ||||
| 	VAR_POST_W, | ||||
| 	VAR_POST_WAFFLE, | ||||
|  | ||||
| @ -439,6 +439,7 @@ VariationList<T>::VariationList() | ||||
| 	ADDPREPOSTREGVAR(Gnarly) | ||||
| 	ADDPREPOSTREGVAR(Inkdrop) | ||||
| 	ADDPREPOSTREGVAR(HexModulus) | ||||
| 	ADDPREPOSTREGVAR(Vignette) | ||||
| 	//ADDPREPOSTREGVAR(LinearXZ) | ||||
| 	//ADDPREPOSTREGVAR(LinearYZ) | ||||
| 	//DC are special. | ||||
|  | ||||
| @ -2395,8 +2395,8 @@ public: | ||||
| 	{ | ||||
| 		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); | ||||
| 		m_PrecalcC = std::cos(a) * m_R * std::cos(a) / m_Divisor; | ||||
| 		m_PrecalcD = std::cos(a) * m_R * std::sin(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) / Zeps(m_Divisor); | ||||
| 		m_HalfC = m_PrecalcC / 2; | ||||
| 		m_HalfD = m_PrecalcD / 2; | ||||
| 		m_Coeff = m_PrecalcD == 0 ? 0 : T(-0.095) * m_Spread / m_PrecalcD; | ||||
| @ -7564,6 +7564,199 @@ private: | ||||
| 	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(Waves2B, waves2b, WAVES2B) | ||||
| MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN) | ||||
| @ -7634,4 +7827,5 @@ MAKEPREPOSTPARVAR(Waves23, waves23, WAVES23) | ||||
| MAKEPREPOSTPARVAR(Waves42, waves42, WAVES42) | ||||
| MAKEPREPOSTPARVAR(Waves3, waves3, WAVES3) | ||||
| MAKEPREPOSTPARVAR(Waves4, waves4, WAVES4) | ||||
| MAKEPREPOSTPARVAR(Vignette, vignette, VIGNETTE) | ||||
| } | ||||
|  | ||||
| @ -1198,7 +1198,15 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur | ||||
| 			std::string periterweights; | ||||
|  | ||||
| 			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")) | ||||
| 			{ | ||||
|  | ||||
| @ -58,7 +58,7 @@ | ||||
|     <enum>QFrame::NoFrame</enum> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string><html><head/><body><p align="center"><span style=" font-size:10pt;">Fractorium 1.0.0.20</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 1.0.0.21</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> | ||||
|  | ||||
| @ -382,8 +382,8 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) | ||||
| 	{ | ||||
| 		auto combo = ui.CurrentXformCombo; | ||||
| 		bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); | ||||
| 		int times = 3; | ||||
| 		int ftimes = 2; | ||||
| 		const int times = 3; | ||||
| 		const int ftimes = 2; | ||||
|  | ||||
| 		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) | ||||
| 			{ | ||||
| 				int val = ke->key() - (int)Qt::Key_F1; | ||||
| 				const int val = ke->key() - (int)Qt::Key_F1; | ||||
|  | ||||
| 				if (val < combo->count()) | ||||
| 					combo->setCurrentIndex(val); | ||||
| @ -417,10 +417,10 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) | ||||
| 		} | ||||
| 		else if (o == this) | ||||
| 		{ | ||||
| 			auto focusedctrlEdit = dynamic_cast<QLineEdit*>(this->focusWidget()); | ||||
| 			auto focusedctrlSpin = dynamic_cast<QSpinBox*>(this->focusWidget()); | ||||
| 			auto focusedctrlDblSpin = dynamic_cast<QDoubleSpinBox*>(this->focusWidget()); | ||||
| 			auto focusedctrlCombo = dynamic_cast<QComboBox*>(this->focusWidget()); | ||||
| 			const auto focusedctrlEdit = dynamic_cast<QLineEdit*>(this->focusWidget()); | ||||
| 			const auto focusedctrlSpin = dynamic_cast<QSpinBox*>(this->focusWidget()); | ||||
| 			const auto focusedctrlDblSpin = dynamic_cast<QDoubleSpinBox*>(this->focusWidget()); | ||||
| 			const auto focusedctrlCombo = dynamic_cast<QComboBox*>(this->focusWidget()); | ||||
|  | ||||
| 			if (!focusedctrlEdit && | ||||
| 					!focusedctrlSpin && | ||||
| @ -434,11 +434,11 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) | ||||
| 				double zoom = 1; | ||||
| 				double rot = 1; | ||||
| 				double grow = 0.01; | ||||
| 				bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); | ||||
| 				bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); | ||||
| 				const bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); | ||||
| 				const bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); | ||||
| 				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(); | ||||
| 					vdist = std::abs(r->UpperRightY() - r->LowerLeftY()) * 0.01 * m_Controller->AffineScaleLockedToCurrent(); | ||||
|  | ||||
| @ -8745,7 +8745,7 @@ | ||||
|     <string>Pre</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Show/Hide Pre Affines</string> | ||||
|     <string>Show/Hide Pre Affines (P)</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="ActionDrawAllPreAffines"> | ||||
| @ -8756,7 +8756,7 @@ | ||||
|     <string>All</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Show All Pre Affines</string> | ||||
|     <string>Show All Pre Affines (L)</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="ActionDrawPostAffines"> | ||||
| @ -8767,7 +8767,7 @@ | ||||
|     <string>Post</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Show/Hide Post Affines</string> | ||||
|     <string>Show/Hide Post Affines (Shift + P)</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="ActionDrawAllPostAffines"> | ||||
| @ -8778,7 +8778,7 @@ | ||||
|     <string>All</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Show All Post Affines</string> | ||||
|     <string>Show All Post Affines (Shift + L)</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="ActionCreateReferenceFile"> | ||||
|  | ||||
| @ -7,10 +7,11 @@ | ||||
| void Fractorium::InitLibraryUI() | ||||
| { | ||||
| 	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(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.SequenceStopPreviewsButton,  SIGNAL(clicked(bool)), this, SLOT(OnSequenceStopPreviewsButtonClicked(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> | ||||
| 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++) | ||||
| 		{ | ||||
| @ -89,10 +90,10 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex() | ||||
| { | ||||
| 	int index = 0; | ||||
| 	QTreeWidgetItem* item = nullptr; | ||||
| 	auto tree = ui.LibraryTree; | ||||
| 	const auto tree = ui.LibraryTree; | ||||
| 	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. | ||||
| 		{ | ||||
| @ -117,7 +118,7 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex() | ||||
| /// <param name="h">The height of the bitmap</param> | ||||
| 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()); | ||||
| 	item->SetImage(m_PreviewVec, w, h); | ||||
| } | ||||
| @ -131,9 +132,9 @@ template <typename T> | ||||
| void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update) | ||||
| { | ||||
| 	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. | ||||
| 		{ | ||||
| @ -166,11 +167,10 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex) | ||||
| { | ||||
| 	uint size = 64; | ||||
| 	uint i = 0; | ||||
| 	auto tree = m_Fractorium->ui.LibraryTree; | ||||
| 	const auto tree = m_Fractorium->ui.LibraryTree; | ||||
| 	vector<byte> v(size * size * 4); | ||||
| 	StopAllPreviewRenderers(); | ||||
| 	tree->clear(); | ||||
| 	QCoreApplication::processEvents(); | ||||
| 	auto fileItem = new QTreeWidgetItem(tree); | ||||
| 	QFileInfo info(m_EmberFile.m_Filename); | ||||
| 	fileItem->setText(0, info.fileName()); | ||||
| @ -205,13 +205,13 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex) | ||||
| template <typename T> | ||||
| void FractoriumEmberController<T>::UpdateLibraryTree() | ||||
| { | ||||
| 	uint size = 64; | ||||
| 	const uint size = 64; | ||||
| 	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)) | ||||
| 	{ | ||||
| 		int origChildCount = top->childCount(); | ||||
| 		const int origChildCount = top->childCount(); | ||||
| 		int i = origChildCount; | ||||
|  | ||||
| 		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 | ||||
| 	{ | ||||
| 		auto tree = m_Fractorium->ui.LibraryTree; | ||||
| 		const auto tree = m_Fractorium->ui.LibraryTree; | ||||
|  | ||||
| 		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; | ||||
|  | ||||
| 			if (emberItem->text(0).isEmpty())//Prevent empty string. | ||||
| 			if (newName.empty())//Prevent empty string. | ||||
| 			{ | ||||
| 				emberItem->UpdateEditText(); | ||||
| 				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. | ||||
| 			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. | ||||
| @ -281,7 +280,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i | ||||
| 		} | ||||
| 		else if (auto parentItem = dynamic_cast<QTreeWidgetItem*>(item)) | ||||
| 		{ | ||||
| 			QString text = parentItem->text(0); | ||||
| 			auto text = parentItem->text(0); | ||||
|  | ||||
| 			if (text != "") | ||||
| 			{ | ||||
| @ -298,7 +297,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| @ -334,9 +333,9 @@ template <typename T> | ||||
| void FractoriumEmberController<T>::MoveLibraryItems(const QModelIndexList& items, int destRow) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	auto startRow = items[0].row(); | ||||
| 	auto tree = m_Fractorium->ui.LibraryTree; | ||||
| 	auto top = tree->topLevelItem(0); | ||||
| 	const auto startRow = items[0].row(); | ||||
| 	const auto tree = m_Fractorium->ui.LibraryTree; | ||||
| 	const auto top = tree->topLevelItem(0); | ||||
| 	list<string> names; | ||||
|  | ||||
| 	for (auto& item : items) | ||||
| @ -344,7 +343,7 @@ void FractoriumEmberController<T>::MoveLibraryItems(const QModelIndexList& items | ||||
| 			names.push_back(temp->m_Name); | ||||
|  | ||||
| 	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); | ||||
|  | ||||
| @ -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. | ||||
| 	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); | ||||
|  | ||||
| @ -421,9 +420,9 @@ void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreview | ||||
|  | ||||
| 	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); | ||||
|  | ||||
| 			for (int i = 0; i < childCount; i++) | ||||
| @ -469,13 +468,12 @@ void FractoriumEmberController<T>::StopAllPreviewRenderers() | ||||
| template <typename T> | ||||
| void FractoriumEmberController<T>::FillSequenceTree() | ||||
| { | ||||
| 	uint size = 64; | ||||
| 	const uint size = 64; | ||||
| 	uint i = 0; | ||||
| 	auto tree = m_Fractorium->ui.SequenceTree; | ||||
| 	const auto tree = m_Fractorium->ui.SequenceTree; | ||||
| 	vector<byte> v(size * size * 4); | ||||
| 	m_SequencePreviewRenderer->Stop(); | ||||
| 	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); | ||||
| 	QFileInfo info(m_SequenceFile.m_Filename); | ||||
| 	fileItem->setText(0, info.fileName()); | ||||
| @ -512,7 +510,7 @@ void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item | ||||
| { | ||||
| 	if (item == m_Fractorium->ui.SequenceTree->topLevelItem(0)) | ||||
| 	{ | ||||
| 		QString text = item->text(0); | ||||
| 		auto text = item->text(0); | ||||
|  | ||||
| 		if (text != "") | ||||
| 			m_SequenceFile.m_Filename = text; | ||||
| @ -521,7 +519,7 @@ void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item | ||||
|  | ||||
| void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col) | ||||
| { | ||||
| 	if (ui.SequenceTree->topLevelItemCount()) | ||||
| 	if (item && ui.SequenceTree->topLevelItemCount()) | ||||
| 		m_Controller->SequenceTreeItemChanged(item, col); | ||||
| } | ||||
|  | ||||
| @ -549,9 +547,9 @@ void Fractorium::OnSequenceStopPreviewsButtonClicked(bool checked) { m_Controlle | ||||
| /// </summary> | ||||
| 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.SequenceStartFlameSpinBox->setMinimum(0); | ||||
| 		ui.SequenceStartFlameSpinBox->setMaximum(count); | ||||
| @ -581,33 +579,33 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked() | ||||
| 	auto& ui = m_Fractorium->ui; | ||||
| 	auto s = m_Fractorium->m_Settings; | ||||
| 	//Bools for determining whether to use hard coded vs. random values. | ||||
| 	bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked(); | ||||
| 	bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked(); | ||||
| 	bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked(); | ||||
| 	bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked(); | ||||
| 	bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked(); | ||||
| 	const bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked(); | ||||
| 	const bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked(); | ||||
| 	const bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked(); | ||||
| 	const bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked(); | ||||
| 	const bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked(); | ||||
| 	//The direction to rotate the loops. | ||||
| 	bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked(); | ||||
| 	bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked(); | ||||
| 	const bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked(); | ||||
| 	const bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked(); | ||||
| 	//Whether to stagger, default is 1 which means no stagger. | ||||
| 	double stagger = ui.SequenceStaggerSpinBox->value(); | ||||
| 	double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value(); | ||||
| 	const double stagger = ui.SequenceStaggerSpinBox->value(); | ||||
| 	const double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value(); | ||||
| 	//Rotations on keyframes. | ||||
| 	double rots = ui.SequenceRotationsSpinBox->value(); | ||||
| 	double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value(); | ||||
| 	const double rots = ui.SequenceRotationsSpinBox->value(); | ||||
| 	const double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value(); | ||||
| 	//Number of frames it takes to rotate a keyframe. | ||||
| 	int framesPerRot = ui.SequenceFramesPerRotSpinBox->value(); | ||||
| 	int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value(); | ||||
| 	const int framesPerRot = ui.SequenceFramesPerRotSpinBox->value(); | ||||
| 	const int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value(); | ||||
| 	//Number of frames it takes to interpolate. | ||||
| 	int framesBlend = ui.SequenceBlendFramesSpinBox->value(); | ||||
| 	int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value(); | ||||
| 	const int framesBlend = ui.SequenceBlendFramesSpinBox->value(); | ||||
| 	const int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value(); | ||||
| 	//Number of rotations performed during interpolation. | ||||
| 	int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value(); | ||||
| 	int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value(); | ||||
| 	size_t start = ui.SequenceStartFlameSpinBox->value(); | ||||
| 	size_t stop = ui.SequenceStopFlameSpinBox->value(); | ||||
| 	size_t startCount = ui.SequenceStartCountSpinBox->value(); | ||||
| 	size_t keyFrames = (stop - start) + 1; | ||||
| 	const int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value(); | ||||
| 	const int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value(); | ||||
| 	const size_t start = ui.SequenceStartFlameSpinBox->value(); | ||||
| 	const size_t stop = ui.SequenceStopFlameSpinBox->value(); | ||||
| 	const size_t startCount = ui.SequenceStartCountSpinBox->value(); | ||||
| 	const size_t keyFrames = (stop - start) + 1; | ||||
| 	size_t frameCount = 0; | ||||
| 	double frames = 0; | ||||
| 	vector<pair<size_t, size_t>> devices;//Dummy. | ||||
| @ -674,18 +672,18 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked() | ||||
| 	double blend; | ||||
| 	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. | ||||
| 	auto padding = streamsize(std::log10(frames)) + 1; | ||||
| 	const auto padding = streamsize(std::log10(frames)) + 1; | ||||
| 	auto it = Advance(m_EmberFile.m_Embers.begin(), start); | ||||
|  | ||||
| 	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; | ||||
|  | ||||
| 		if (rotations > 0) | ||||
| 		{ | ||||
| 			double rotFrames = randFramesRot ? m_Rand.Frand<double>(framesPerRot, framesPerRotMax) : framesPerRot; | ||||
| 			size_t roundFrames = size_t(std::round(rotFrames * rotations)); | ||||
| 			const auto rotFrames = randFramesRot ? m_Rand.Frand<double>(framesPerRot, framesPerRotMax) : framesPerRot; | ||||
| 			const auto roundFrames = size_t(std::round(rotFrames * rotations)); | ||||
|  | ||||
| 			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. | ||||
| 			embers[1] = *(++it2);//Get the next ember to be used with blending below. | ||||
| 			size_t blendFrames = randBlend ? m_Rand.Frand<double>(framesBlend, framesBlendMax) : framesBlend; | ||||
| 			double d = randBlendRot ? m_Rand.Frand<double>(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend); | ||||
| 			size_t rpb = size_t(std::round(d)); | ||||
| 			const auto blendFrames = randBlend ? m_Rand.Frand<double>(framesBlend, framesBlendMax) : framesBlend; | ||||
| 			const auto d = randBlendRot ? m_Rand.Frand<double>(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend); | ||||
| 			const auto rpb = size_t(std::round(d)); | ||||
|  | ||||
| 			if (randStagger) | ||||
| 				tools.Stagger(m_Rand.Frand<double>(stagger, staggerMax)); | ||||
| @ -722,7 +720,7 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked() | ||||
| 			{ | ||||
| 				//if (frame == 43) | ||||
| 				//	cout << frame << endl; | ||||
| 				bool seqFlag = frame == 0 || (frame == blendFrames - 1); | ||||
| 				const auto seqFlag = frame == 0 || (frame == blendFrames - 1); | ||||
| 				blend = frame / double(blendFrames); | ||||
| 				result.Clear(); | ||||
| 				tools.SpinInter(&embers[0], nullptr, result, startCount + frameCount++, seqFlag, blend, rpb, loopsBlendCw); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Michel Mastriani
					Michel Mastriani