/**
 * Mandelbulber v2, a 3D fractal generator  _%}}i*<.        ____                _______
 * Copyright (C) 2017 Mandelbulber Team   _>]|=||i=i<,     / __ \___  ___ ___  / ___/ /
 *                                        \><||i|=>>%)    / /_/ / _ \/ -_) _ \/ /__/ /__
 * This file is part of Mandelbulber.     )<=i=]=|=i<>    \____/ .__/\__/_//_/\___/____/
 * The project is licensed under GPLv3,   -<>>=|><|||`        /_/
 * see also COPYING file in this folder.    ~+{i%+++
 *
 *  Scale varies smoothly based on iteration parameters.

 * This file has been autogenerated by tools/populateUiInformation.php
 * from the function "TransfScaleVaryVCLIteration" in the file fractal_formulas.cpp
 * D O    N O T    E D I T    T H I S    F I L E !
 */

REAL4 TransfScaleVaryVCLIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
{
	REAL para = 0.0f;

	if (fractal->Cpara.enabledLinear)
	{
		para = fractal->Cpara.para0; // parameter value at iter 0
		REAL temp0 = para;
		REAL tempA = fractal->Cpara.paraA;
		REAL tempB = fractal->Cpara.paraB;
		REAL tempC = fractal->Cpara.paraC;
		REAL lengthAB = fractal->Cpara.iterB - fractal->Cpara.iterA;
		REAL lengthBC = fractal->Cpara.iterC - fractal->Cpara.iterB;
		REAL grade1 = native_divide((tempA - temp0), fractal->Cpara.iterA);
		REAL grade2 = native_divide((tempB - tempA), lengthAB);
		REAL grade3 = native_divide((tempC - tempB), lengthBC);

		// slopes
		if (aux->i < fractal->Cpara.iterA)
		{
			para = temp0 + (aux->i * grade1);
		}
		if (aux->i < fractal->Cpara.iterB && aux->i >= fractal->Cpara.iterA)
		{
			para = mad(grade2, (aux->i - fractal->Cpara.iterA), tempA);
		}
		if (aux->i >= fractal->Cpara.iterB)
		{
			para = mad(grade3, (aux->i - fractal->Cpara.iterB), tempB);
		}

		// Curvi part on "true"
		if (fractal->Cpara.enabledCurves)
		{
			REAL paraAdd = 0.0f;
			REAL paraIt;
			if (lengthAB > 2.0f * fractal->Cpara.iterA) // stop  error, todo fix.
			{
				REAL curve1 = native_divide((grade2 - grade1), (4.0f * fractal->Cpara.iterA));
				REAL tempL = lengthAB - fractal->Cpara.iterA;
				REAL curve2 = native_divide((grade3 - grade2), (4.0f * tempL));
				if (aux->i < 2 * fractal->Cpara.iterA)
				{
					paraIt = tempA - fabs(tempA - aux->i);
					paraAdd = paraIt * paraIt * curve1;
				}
				if (aux->i >= 2 * fractal->Cpara.iterA && aux->i < fractal->Cpara.iterB + tempL)
				{
					paraIt = tempB - fabs(tempB * aux->i);
					paraAdd = paraIt * paraIt * curve2;
				}
				para += paraAdd;
			}
		}
	}
	// Parabolic
	REAL paraAddP0 = 0.0f;
	if (fractal->Cpara.enabledParabFalse)
	{ // parabolic = paraOffset + iter *slope + (iter *iter *scale)
		paraAddP0 = fractal->Cpara.parabOffset + (aux->i * fractal->Cpara.parabSlope)
								+ (aux->i * aux->i * 0.001f * fractal->Cpara.parabScale);
	}
	para += paraAddP0;

	z *= para; // using the parameter
	aux->DE = mad(aux->DE, fabs(para), 1.0f);
	return z;
}