mirror of
				https://bitbucket.org/mfeemster/fractorium.git
				synced 2025-11-03 17:50:27 -05:00 
			
		
		
		
	1.0.0.19 Re-release
--Bug fixes -Blur Cuve never worked with strips. -Images with temporal filter width values below 0.6 would sometimes create blank images.
This commit is contained in:
		@ -13,7 +13,7 @@
 | 
			
		||||
	<!--
 | 
			
		||||
	Change this for every release.
 | 
			
		||||
	-->
 | 
			
		||||
	<?define ProductCode="{8A8580F6-017D-455D-899E-C0FF91ECEB68}"?>
 | 
			
		||||
	<?define ProductCode="{490402BA-697C-4814-92E8-5F161B7813B5}"?>
 | 
			
		||||
	
 | 
			
		||||
	<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
 | 
			
		||||
		<Package
 | 
			
		||||
 | 
			
		||||
@ -22,13 +22,14 @@
 | 
			
		||||
 -Custom palettes were not being read correctly on non ANSI machines.
 | 
			
		||||
 -EmberAnimate.exe was using 1-based indexing for filenames, but Fractorium and all of the documentation was using 0-based indexing. Make all use 0-based indexing.
 | 
			
		||||
 -The left header column in the xaos visualization table had somehow disappeared.
 | 
			
		||||
 -Fix  OpenCL compilation bug when using Depth Blur with AMD on Mac.
 | 
			
		||||
 -Fix OpenCL compilation bug when using Depth Blur with AMD on Mac.
 | 
			
		||||
 -Blur Cuve never worked with strips.
 | 
			
		||||
 -Images with temporal filter width values below 0.6 would sometimes create blank images.
 | 
			
		||||
 | 
			
		||||
--Code changes
 | 
			
		||||
 -Make all iterators on the CPU use a temporary point.
 | 
			
		||||
 -DoubleSpinBox now has a boolean which specifies whether it clears its selection on enter. Default true.
 | 
			
		||||
 -Make AddXformsWithXaos() be a static member of FractoriumEmberController for quicker build times.
 | 
			
		||||
 -Remove the unused field m_RotCenterY from Ember.
 | 
			
		||||
 -Make a #define for fma() testing, but seems to make no difference.
 | 
			
		||||
 -Optimize some of the OpenCL iteration kernel generation code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -142,6 +142,20 @@ public:
 | 
			
		||||
		m_CarCenterY = m_CarLlY + m_CarHalfY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Assign values to the cached half width/height fields.
 | 
			
		||||
	/// This is only done manually here and is used when rendering strips
 | 
			
		||||
	/// because a cached copy of these is required because the real values
 | 
			
		||||
	/// change with the assignment of each temporary strip ember object.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="x">The cached value equal to half of the cartesian width of the x plane</param>
 | 
			
		||||
	/// <param name="y">The cached value equal to half of the cartesian width of the y plane</param>
 | 
			
		||||
	void UpdateCachedHalf(T x, T y)
 | 
			
		||||
	{
 | 
			
		||||
		m_CachedCarHalfX = x;
 | 
			
		||||
		m_CachedCarHalfY = y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Convert a cartesian x, y coordinate to a raster x, y coordinate.
 | 
			
		||||
	/// This will flip the Y coordinate, so points that hit the bottom of the cartesian plane will
 | 
			
		||||
@ -237,6 +251,8 @@ public:
 | 
			
		||||
	inline T PadCarUrY() const { return m_PadCarUrY; }
 | 
			
		||||
	inline T CarHalfX() const { return m_CarHalfX; }
 | 
			
		||||
	inline T CarHalfY() const { return m_CarHalfY; }
 | 
			
		||||
	inline T CachedCarHalfX() const { return m_CachedCarHalfX; }
 | 
			
		||||
	inline T CachedCarHalfY() const { return m_CachedCarHalfY; }
 | 
			
		||||
	inline T CarCenterX() const { return m_CarCenterX; }
 | 
			
		||||
	inline T CarCenterY() const { return m_CarCenterY; }
 | 
			
		||||
 | 
			
		||||
@ -251,6 +267,7 @@ private:
 | 
			
		||||
	T m_CarLlX, m_CarLlY, m_CarUrX, m_CarUrY;//The bounds of the cartesian plane.
 | 
			
		||||
	T m_PadCarLlX, m_PadCarLlY, m_PadCarUrX, m_PadCarUrY;//The bounds of the cartesian plane padded by one raster row and column on each side.
 | 
			
		||||
	T m_CarHalfX, m_CarHalfY;//The distance from the center of the of the cartesian plane to the edges.
 | 
			
		||||
	T m_CachedCarHalfX, m_CachedCarHalfY;//The cahced distance from the center of the of the cartesian plane to the edges, needed when rendering strips.
 | 
			
		||||
	T m_CarCenterX, m_CarCenterY;//The center of the cartesian plane.
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1238,8 +1238,8 @@ public:
 | 
			
		||||
		z = m_CamMat[1][2] * point.m_Y + m_CamMat[2][2] * z;
 | 
			
		||||
		zr = Zeps(1 - m_CamPerspective * z);
 | 
			
		||||
		sincos(t, &dsin, &dcos);
 | 
			
		||||
		T prcx = point.m_X / ctr.CarHalfX();
 | 
			
		||||
		T prcy = y / ctr.CarHalfY();
 | 
			
		||||
		T prcx = point.m_X / ctr.CachedCarHalfX();
 | 
			
		||||
		T prcy = y / ctr.CachedCarHalfY();
 | 
			
		||||
		T dist = VarFuncs<T>::Hypot(prcx, prcy) * 10;
 | 
			
		||||
		T scale = m_BlurCurve ? (Sqr(dist) / (4 * m_BlurCurve)) : T(1);
 | 
			
		||||
		T dr = rand.Frand01<T>() * (m_BlurCoef * scale) * z;
 | 
			
		||||
@ -1262,8 +1262,8 @@ public:
 | 
			
		||||
		T y = m_CamMat[0][1] * point.m_X + m_CamMat[1][1] * point.m_Y + m_CamMat[2][1] * z;
 | 
			
		||||
		z = m_CamMat[0][2] * point.m_X + m_CamMat[1][2] * point.m_Y + m_CamMat[2][2] * z;
 | 
			
		||||
		T zr = Zeps(1 - m_CamPerspective * z);
 | 
			
		||||
		T prcx = x / ctr.CarHalfX();
 | 
			
		||||
		T prcy = y / ctr.CarHalfY();
 | 
			
		||||
		T prcx = x / ctr.CachedCarHalfX();
 | 
			
		||||
		T prcy = y / ctr.CachedCarHalfY();
 | 
			
		||||
		T dist = VarFuncs<T>::Hypot(prcx, prcy) * 10;
 | 
			
		||||
		T scale = m_BlurCurve ? (Sqr(dist) / (4 * m_BlurCurve)) : T(1);
 | 
			
		||||
		T dr = rand.Frand01<T>() * (m_BlurCoef * scale) * z;
 | 
			
		||||
 | 
			
		||||
@ -43,6 +43,7 @@ void Renderer<T, bucketT>::AddEmber(Ember<T>& ember)
 | 
			
		||||
		if (m_Embers.size() == 1)
 | 
			
		||||
			m_Ember = m_Embers[0];
 | 
			
		||||
	}, eProcessAction::FULL_RENDER);
 | 
			
		||||
	Prepare();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
@ -73,6 +74,21 @@ bool Renderer<T, bucketT>::AssignIterator()
 | 
			
		||||
/// Virtual processing functions overriden from RendererBase.
 | 
			
		||||
/// </summary>
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Prepare values for the filters, bounds, quality and camera.
 | 
			
		||||
/// </summary>
 | 
			
		||||
template <typename T, typename bucketT>
 | 
			
		||||
void Renderer<T, bucketT>::Prepare()
 | 
			
		||||
{
 | 
			
		||||
	bool b = false;
 | 
			
		||||
	CreateSpatialFilter(b);
 | 
			
		||||
	CreateTemporalFilter(b);
 | 
			
		||||
	ComputeBounds();
 | 
			
		||||
	ComputeQuality();
 | 
			
		||||
	ComputeCamera();
 | 
			
		||||
	m_CarToRas.UpdateCachedHalf(m_CarToRas.CarHalfX(), m_CarToRas.CarHalfY());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Compute the bounds of the histogram and density filtering buffers.
 | 
			
		||||
/// These are affected by the final requested dimensions, spatial and density
 | 
			
		||||
@ -156,14 +172,7 @@ void Renderer<T, bucketT>::SetEmber(const Ember<T>& ember, eProcessAction action
 | 
			
		||||
	}, action);
 | 
			
		||||
 | 
			
		||||
	if (prep)
 | 
			
		||||
	{
 | 
			
		||||
		bool b = false;
 | 
			
		||||
		CreateSpatialFilter(b);
 | 
			
		||||
		CreateTemporalFilter(b);
 | 
			
		||||
		ComputeBounds();
 | 
			
		||||
		ComputeQuality();
 | 
			
		||||
		ComputeCamera();
 | 
			
		||||
	}
 | 
			
		||||
		Prepare();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
@ -183,7 +192,9 @@ void Renderer<T, bucketT>::SetEmber(const C& embers)
 | 
			
		||||
 | 
			
		||||
		if (!m_Embers.empty())
 | 
			
		||||
			m_Ember = m_Embers[0];
 | 
			
		||||
 | 
			
		||||
	}, eProcessAction::FULL_RENDER);
 | 
			
		||||
	Prepare();//Always prepare with a collection.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
@ -204,7 +215,9 @@ void Renderer<T, bucketT>::MoveEmbers(vector<Ember<T>>& embers)
 | 
			
		||||
 | 
			
		||||
		if (!m_Embers.empty())
 | 
			
		||||
			m_Ember = m_Embers[0];
 | 
			
		||||
 | 
			
		||||
	}, eProcessAction::FULL_RENDER);
 | 
			
		||||
	Prepare();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, typename bucketT>
 | 
			
		||||
@ -217,7 +230,9 @@ void Renderer<T, bucketT>::SetExternalEmbersPointer(vector<Ember<T>>* embers)
 | 
			
		||||
 | 
			
		||||
		if (!m_EmbersP->empty())
 | 
			
		||||
			m_Ember = (*m_EmbersP)[0];
 | 
			
		||||
 | 
			
		||||
	}, eProcessAction::FULL_RENDER);
 | 
			
		||||
	Prepare();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
@ -511,6 +526,7 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
 | 
			
		||||
		{
 | 
			
		||||
			ComputeQuality();
 | 
			
		||||
			ComputeCamera();
 | 
			
		||||
			//m_CarToRas.UpdateCachedHalf(m_CarToRas.CarHalfX(), m_CarToRas.CarHalfY());
 | 
			
		||||
			MakeDmap(colorScalar);//For each temporal sample, the palette m_Dmap needs to be re-created with color scalar. 1 if no temporal samples.
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,7 @@ public:
 | 
			
		||||
	bool AssignIterator();
 | 
			
		||||
 | 
			
		||||
	//Virtual processing functions overriden from RendererBase.
 | 
			
		||||
	virtual void Prepare() override;
 | 
			
		||||
	virtual void ComputeBounds() override;
 | 
			
		||||
	virtual void ComputeQuality() override;
 | 
			
		||||
	virtual void ComputeCamera() override;
 | 
			
		||||
 | 
			
		||||
@ -121,6 +121,7 @@ public:
 | 
			
		||||
	virtual bool CreateDEFilter(bool& newAlloc) = 0;
 | 
			
		||||
	virtual bool CreateSpatialFilter(bool& newAlloc) = 0;
 | 
			
		||||
	virtual bool CreateTemporalFilter(bool& newAlloc) = 0;
 | 
			
		||||
	virtual void Prepare() = 0;
 | 
			
		||||
	virtual void ComputeBounds() = 0;
 | 
			
		||||
	virtual void ComputeQuality() = 0;
 | 
			
		||||
	virtual void ComputeCamera() = 0;
 | 
			
		||||
 | 
			
		||||
@ -850,7 +850,7 @@ public:
 | 
			
		||||
		adjustedEmber.m_FinalRasH = static_cast<size_t>(std::ceil(ember.m_FinalRasH  * scalar));
 | 
			
		||||
		adjustedEmber.m_PixelsPerUnit *= scalar;
 | 
			
		||||
		adjustedEmber.m_TemporalSamples = 1;
 | 
			
		||||
		m_Renderer->SetEmber(adjustedEmber);
 | 
			
		||||
		m_Renderer->SetEmber(adjustedEmber, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
		m_Renderer->EarlyClip(true);
 | 
			
		||||
 | 
			
		||||
		if (m_Renderer->Run(m_FinalImage) != eRenderStatus::RENDER_OK)
 | 
			
		||||
 | 
			
		||||
@ -229,14 +229,19 @@ private:
 | 
			
		||||
		for (i = 0; i < m_Filter.size(); i++)
 | 
			
		||||
			t += m_Filter[i];
 | 
			
		||||
 | 
			
		||||
		if (t == 0.0)
 | 
			
		||||
		if (t == 0.0 || std::isinf(t) || std::isnan(t) || !std::isnormal(t))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		t = T(1.0) / t;
 | 
			
		||||
		t = T(1.0 / t);
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < m_Filter.size(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			m_Filter[i] *= t;
 | 
			
		||||
 | 
			
		||||
			if (std::isinf(t) || std::isnan(t) || !std::isnormal(t))
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -271,9 +276,9 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		return std::exp(-2 * t * t) * std::sqrt(2 / T(M_PI));
 | 
			
		||||
		return T(std::exp(-2 * t * t) * std::sqrt(2 / M_PI));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -300,13 +305,13 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
 | 
			
		||||
		if (t < 1)
 | 
			
		||||
			return ((T(2.0) * t - T(3.0)) * t * t + T(1.0));
 | 
			
		||||
			return T((2.0 * t - 3.0) * t * t + 1.0);
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@ -334,7 +339,7 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if ((t > T(-0.5)) && (t <= T(0.5)))
 | 
			
		||||
			return 1;
 | 
			
		||||
@ -365,7 +370,7 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
@ -399,19 +404,19 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		//box (*) box (*) box.
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
 | 
			
		||||
		if (t < T(0.5))
 | 
			
		||||
			return (T(0.75) - (t * t));
 | 
			
		||||
			return T(0.75 - (t * t));
 | 
			
		||||
 | 
			
		||||
		if (t < T(1.5))
 | 
			
		||||
		{
 | 
			
		||||
			t = (t - T(1.5));
 | 
			
		||||
			return (T(0.5) * (t * t));
 | 
			
		||||
			t = T(t - 1.5);
 | 
			
		||||
			return T(0.5 * (t * t));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
@ -440,7 +445,7 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		//box (*) box (*) box (*) box.
 | 
			
		||||
		T tt;
 | 
			
		||||
@ -451,12 +456,12 @@ public:
 | 
			
		||||
		if (t < 1)
 | 
			
		||||
		{
 | 
			
		||||
			tt = t * t;
 | 
			
		||||
			return ((T(0.5) * tt * t) - tt + (T(2.0) / T(3.0)));
 | 
			
		||||
			return T((0.5 * tt * t) - tt + (2.0 / 3.0));
 | 
			
		||||
		}
 | 
			
		||||
		else if (t < 2)
 | 
			
		||||
		{
 | 
			
		||||
			t = 2 - t;
 | 
			
		||||
			return ((T(1.0) / T(6.0)) * (t * t * t));
 | 
			
		||||
			return T((1.0 / 6.0) * (t * t * t));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
@ -485,7 +490,7 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
@ -519,7 +524,7 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
@ -553,28 +558,28 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		T tt = t * t;
 | 
			
		||||
		const T b = T(1) / T(3);
 | 
			
		||||
		const T c = T(1) / T(3);
 | 
			
		||||
		const T b = T(1.0 / 3.0);
 | 
			
		||||
		const T c = T(1.0 / 3.0);
 | 
			
		||||
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			t = -t;
 | 
			
		||||
 | 
			
		||||
		if (t < 1)
 | 
			
		||||
		{
 | 
			
		||||
			t = (((T(12.0) - T(9.0) * b - T(6.0) * c) * (t * tt))
 | 
			
		||||
				 + ((T(-18.0) + T(12.0) * b + T(6.0) * c) * tt)
 | 
			
		||||
				 + (T(6.0) - 2 * b));
 | 
			
		||||
			t = T(((12.0 - 9.0 * b - 6.0 * c) * (t * tt))
 | 
			
		||||
				  + ((-18.0 + 12.0 * b + 6.0 * c) * tt)
 | 
			
		||||
				  + (6.0 - 2 * b));
 | 
			
		||||
			return t / 6;
 | 
			
		||||
		}
 | 
			
		||||
		else if (t < 2)
 | 
			
		||||
		{
 | 
			
		||||
			t = (((T(-1.0) * b - T(6.0) * c) * (t * tt))
 | 
			
		||||
				 + ((T(6.0) * b + T(30.0) * c) * tt)
 | 
			
		||||
				 + ((T(-12.0) * b - T(48.0) * c) * t)
 | 
			
		||||
				 + (T(8.0) * b + 24 * c));
 | 
			
		||||
			t = T(((-1.0 * b - 6.0 * c) * (t * tt))
 | 
			
		||||
				  + ((6.0 * b + 30.0 * c) * tt)
 | 
			
		||||
				  + ((-12.0 * b - 48.0 * c) * t)
 | 
			
		||||
				  + (8.0 * b + 24 * c));
 | 
			
		||||
			return t / 6;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -604,9 +609,9 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		return (T(0.42) + T(0.5) * std::cos(T(M_PI) * t) + T(0.08) * std::cos(2 * T(M_PI) * t));
 | 
			
		||||
		return T(0.42 + 0.5 * std::cos(M_PI * t) + 0.08 * std::cos(2 * M_PI * t));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -632,22 +637,22 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		if (t < -1)
 | 
			
		||||
			return T(0.5) * (4 + t * (8 + t * (5 + t)));
 | 
			
		||||
			return T(0.5 * (4 + t * (8 + t * (5 + t))));
 | 
			
		||||
 | 
			
		||||
		if (t < 0)
 | 
			
		||||
			return T(0.5) * (2 + t * t * (-5 - 3 * t));
 | 
			
		||||
			return T(0.5 * (2 + t * t * (-5 - 3 * t)));
 | 
			
		||||
 | 
			
		||||
		if (t < 1)
 | 
			
		||||
			return T(0.5) * (2 + t * t * (-5 + 3 * t));
 | 
			
		||||
			return T(0.5 * (2 + t * t * (-5 + 3 * t)));
 | 
			
		||||
 | 
			
		||||
		if (t < 2)
 | 
			
		||||
			return T(0.5) * (4 + t * (-8 + t * (5 - t)));
 | 
			
		||||
			return T(0.5 * (4 + t * (-8 + t * (5 - t))));
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@ -675,9 +680,9 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		return T(0.54) + T(0.46) * std::cos(T(M_PI) * t);
 | 
			
		||||
		return T(0.54 + 0.46 * std::cos(M_PI * t));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -703,9 +708,9 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		return T(0.5) + T(0.5) * std::cos(T(M_PI) * t);
 | 
			
		||||
		return T(0.5 + 0.5 * std::cos(M_PI * t));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -731,19 +736,19 @@ public:
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="t">The value to apply the filter to</param>
 | 
			
		||||
	/// <returns>The filtered value</returns>
 | 
			
		||||
	virtual T Filter(T t) const
 | 
			
		||||
	virtual T Filter(T t) const override
 | 
			
		||||
	{
 | 
			
		||||
		if (t < -1.5)
 | 
			
		||||
			return 0.0;
 | 
			
		||||
 | 
			
		||||
		if (t < -0.5)
 | 
			
		||||
			return T(0.5) * (t + T(1.5)) * (t + T(1.5));
 | 
			
		||||
			return T(0.5 * (t + 1.5) * (t + 1.5));
 | 
			
		||||
 | 
			
		||||
		if (t < 0.5)
 | 
			
		||||
			return T(0.75) - (t * t);
 | 
			
		||||
			return T(0.75 - (t * t));
 | 
			
		||||
 | 
			
		||||
		if (t < 1.5)
 | 
			
		||||
			return T(0.5) * (t - T(1.5)) * (t - T(1.5));
 | 
			
		||||
			return T(0.5 * (t - 1.5) * (t - 1.5));
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1884,8 +1884,8 @@ void RendererCL<T, bucketT>::ConvertCarToRas(const CarToRas<T>& carToRas)
 | 
			
		||||
	m_CarToRasCL.m_CarLlY = carToRas.CarLlY();
 | 
			
		||||
	m_CarToRasCL.m_CarUrX = carToRas.CarUrX();
 | 
			
		||||
	m_CarToRasCL.m_CarUrY = carToRas.CarUrY();
 | 
			
		||||
	m_CarToRasCL.m_CarHalfX   = carToRas.CarHalfX();
 | 
			
		||||
	m_CarToRasCL.m_CarHalfY   = carToRas.CarHalfY();
 | 
			
		||||
	m_CarToRasCL.m_CarHalfX   = carToRas.CachedCarHalfX();
 | 
			
		||||
	m_CarToRasCL.m_CarHalfY   = carToRas.CachedCarHalfY();
 | 
			
		||||
	m_CarToRasCL.m_CarCenterX = carToRas.CarCenterX();
 | 
			
		||||
	m_CarToRasCL.m_CarCenterY = carToRas.CarCenterY();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -597,6 +597,9 @@ static vector<unique_ptr<Renderer<T, float>>> CreateRenderers(eRendererType rend
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Perform a render which allows for using strips or not.
 | 
			
		||||
/// If an error occurs while rendering any strip, the rendering process stops.
 | 
			
		||||
/// Note this must be called after SetEmber(ember, eProcessAction::FULL_RENDER, true) is called on the renderer.
 | 
			
		||||
/// The last parameter to SetEmber must be true to compute the camera, because is caches certain values that need to be
 | 
			
		||||
/// retained between strips.
 | 
			
		||||
/// </summary>
 | 
			
		||||
/// <param name="renderer">The renderer to use</param>
 | 
			
		||||
/// <param name="ember">The ember to render</param>
 | 
			
		||||
 | 
			
		||||
@ -781,7 +781,7 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt)
 | 
			
		||||
				orig.m_Edits = emberToXml.CreateNewEditdoc(aselp0, aselp1, os.str(), opt.Nick(), opt.Url(), opt.Id(), opt.Comment(), opt.SheepGen(), opt.SheepId());
 | 
			
		||||
				save = orig;
 | 
			
		||||
				SetDefaultTestValues(orig);
 | 
			
		||||
				renderer->SetEmber(orig);
 | 
			
		||||
				renderer->SetEmber(orig, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
 | 
			
		||||
				if (renderer->Run(finalImage) != eRenderStatus::RENDER_OK)
 | 
			
		||||
				{
 | 
			
		||||
 | 
			
		||||
@ -219,7 +219,7 @@ bool EmberRender(int argc, _TCHAR* argv[], EmberOptions& opt)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		stats.Clear();
 | 
			
		||||
		renderer->SetEmber(ember);
 | 
			
		||||
		renderer->SetEmber(ember, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
		renderer->PrepFinalAccumVector(finalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
 | 
			
		||||
 | 
			
		||||
		if (opt.Strips() > 1)
 | 
			
		||||
 | 
			
		||||
@ -1745,7 +1745,7 @@ bool TestAllVarsCLBuild(size_t platform, size_t device, bool printSuccess = true
 | 
			
		||||
 | 
			
		||||
	for (auto& it : embers)
 | 
			
		||||
	{
 | 
			
		||||
		renderer.SetEmber(it);
 | 
			
		||||
		renderer.SetEmber(it, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
 | 
			
		||||
		//if (platform != 0 &&
 | 
			
		||||
		//		((it.GetXform(0)->GetVariationById(eVariationId::VAR_SYNTH) != nullptr) ||//Nvidia OpenCL driver crashes when building too many synths.
 | 
			
		||||
 | 
			
		||||
@ -267,7 +267,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
 | 
			
		||||
 | 
			
		||||
					Output("Image " + ToString<qulonglong>(m_FinishedImageCount.load() + 1) + ":\n" + ComposePath(QString::fromStdString(it.m_Name)));
 | 
			
		||||
					it.m_TemporalSamples = 1;//No temporal sampling.
 | 
			
		||||
					m_Renderer->SetEmber(it);
 | 
			
		||||
					m_Renderer->SetEmber(it, eProcessAction::FULL_RENDER, 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_Stats.Clear();
 | 
			
		||||
					m_RenderTimer.Tic();//Toc() is called in RenderComplete().
 | 
			
		||||
@ -298,7 +298,7 @@ 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.
 | 
			
		||||
			m_Renderer->SetEmber(*m_Ember, isBump ? eProcessAction::KEEP_ITERATING : eProcessAction::FULL_RENDER);
 | 
			
		||||
			m_Renderer->SetEmber(*m_Ember, isBump ? eProcessAction::KEEP_ITERATING : eProcessAction::FULL_RENDER, 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_Stats.Clear();
 | 
			
		||||
			Output(ComposePath(QString::fromStdString(m_Ember->m_Name)));
 | 
			
		||||
@ -1130,7 +1130,7 @@ void FinalRenderPreviewRenderer<T>::PreviewRenderFunc(uint start, uint end)
 | 
			
		||||
	m_PreviewRenderer.EarlyClip(d->EarlyClip());
 | 
			
		||||
	m_PreviewRenderer.YAxisUp(d->YAxisUp());
 | 
			
		||||
	m_PreviewRenderer.Callback(nullptr);
 | 
			
		||||
	m_PreviewRenderer.SetEmber(m_PreviewEmber);
 | 
			
		||||
	m_PreviewRenderer.SetEmber(m_PreviewEmber, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
	m_PreviewRenderer.PrepFinalAccumVector(m_PreviewFinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
 | 
			
		||||
	auto strips = VerifyStrips(m_PreviewEmber.m_FinalRasH, d->Strips(),
 | 
			
		||||
	[&](const string & s) {}, [&](const string & s) {}, [&](const string & s) {});
 | 
			
		||||
 | 
			
		||||
@ -391,7 +391,7 @@ void TreePreviewRenderer<T>::PreviewRenderFunc(uint start, uint end)
 | 
			
		||||
			m_PreviewEmber.m_TemporalSamples = 1;
 | 
			
		||||
			m_PreviewEmber.m_Quality = 25;
 | 
			
		||||
			m_PreviewEmber.m_Supersample = 1;
 | 
			
		||||
			m_PreviewRenderer.SetEmber(m_PreviewEmber);
 | 
			
		||||
			m_PreviewRenderer.SetEmber(m_PreviewEmber, eProcessAction::FULL_RENDER, true);
 | 
			
		||||
 | 
			
		||||
			if (m_PreviewRenderer.Run(m_PreviewFinalImage) == eRenderStatus::RENDER_OK)
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
@ -373,7 +373,7 @@ bool FractoriumEmberController<T>::Render()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i = 0;
 | 
			
		||||
		m_Renderer->SetEmber(m_Ember, action);
 | 
			
		||||
		m_Renderer->SetEmber(m_Ember, action, true);
 | 
			
		||||
 | 
			
		||||
		if (solo != -1)
 | 
			
		||||
			while (auto xform = m_Ember.GetTotalXform(i, forceFinal))
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,9 @@
 | 
			
		||||
/// </summary>
 | 
			
		||||
void ExportUserData()
 | 
			
		||||
{
 | 
			
		||||
    auto exec = new QProcess();
 | 
			
		||||
    exec->setWorkingDirectory(QCoreApplication::applicationDirPath());
 | 
			
		||||
    exec->start("/bin/sh", QStringList() << "fractorium-sh");
 | 
			
		||||
	auto exec = new QProcess();
 | 
			
		||||
	exec->setWorkingDirectory(QCoreApplication::applicationDirPath());
 | 
			
		||||
	exec->start("/bin/sh", QStringList() << "fractorium-sh");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,8 @@ int main(int argc, char* argv[])
 | 
			
		||||
		Fractorium w;
 | 
			
		||||
		w.show();
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        // exporting user data
 | 
			
		||||
        ExportUserData();
 | 
			
		||||
		// exporting user data
 | 
			
		||||
		ExportUserData();
 | 
			
		||||
#endif
 | 
			
		||||
		a.installEventFilter(&w);
 | 
			
		||||
		rv = a.exec();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,9 @@
 | 
			
		||||
fractorium (1.0.0.19d-0ubuntu1) bionic; urgency=low
 | 
			
		||||
 | 
			
		||||
  * release 1.0.0.19
 | 
			
		||||
 | 
			
		||||
 -- Matt Feemster <matt.feemster@gmail.com>  Wed, 18 Mar 2020 19:25:25 -0700
 | 
			
		||||
 | 
			
		||||
fractorium (1.0.0.19c-0ubuntu1) bionic; urgency=low
 | 
			
		||||
 | 
			
		||||
  * release 1.0.0.19
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user