/**
 * Mandelbulber v2, a 3D fractal generator  _%}}i*<.        ____                _______
 * Copyright (C) 2023 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%+++
 *
 * based on M3D tritgridIFS
 * http://www.fractalforums.com/mandelbulb-3d/custom-formulas-and-transforms-release-t17106/

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

REAL4 TransfDIFSTriGridIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
{
	if (fractal->transformCommon.functionEnabledAFalse)
	{
		if (fractal->transformCommon.functionEnabledAxFalse) z.x = fabs(z.x);
		if (fractal->transformCommon.functionEnabledAyFalse) z.y = fabs(z.y);
		if (fractal->transformCommon.functionEnabledAzFalse) z.z = fabs(z.z);
	}
	z += fractal->transformCommon.offset000;

	// polyfold
	if (fractal->transformCommon.functionEnabledPFalse
			&& aux->i >= fractal->transformCommon.startIterationsP
			&& aux->i < fractal->transformCommon.stopIterationsP1)
	{
		z.y = fabs(z.y);
		REAL psi = M_PI_F / fractal->transformCommon.int6;
		psi = fabs(fmod(atan2(z.y, z.x) + psi, 2.0f * psi) - psi);
		REAL len = native_sqrt(z.x * z.x + z.y * z.y);
		z.x = native_cos(psi) * len;
		z.y = native_sin(psi) * len;
	}

	if (fractal->transformCommon.rotationEnabledFalse
			&& aux->i >= fractal->transformCommon.startIterationsR
			&& aux->i < fractal->transformCommon.stopIterationsR1)
		z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, z);
	// tri grid
	REAL4 zc = z;
	zc.z *= fractal->transformCommon.scale1;
	REAL4 off = fractal->transformCommon.offset111;
	REAL a;
	if (!fractal->transformCommon.functionEnabledEFalse)
		a = fabs(zc.x - off.x * floor(zc.x / off.x + 0.5f));
	else
		a = 1000.0f;
	zc.x = zc.x * 0.5f;
	zc.y = zc.y * SQRT_3_F * 0.5f;
	REAL b = zc.x + zc.y;
	b = fabs(b - off.y * floor(b / off.y + 0.5f));
	REAL c = zc.x - zc.y;
	c = fabs(c - off.z * floor(c / off.z + 0.5f));
	REAL tp = min(min(a, b), c) - fractal->transformCommon.offset0;

	if (!fractal->transformCommon.functionEnabledJFalse)
		tp = native_sqrt((tp * tp) + (zc.z * zc.z));
	else
		tp = max(fabs(tp), fabs(zc.z));
	tp -= fractal->transformCommon.offset0005;
	// plane
	if (fractal->transformCommon.functionEnabledDFalse)
	{
		REAL d =
			fabs(aux->const_c.z - fractal->transformCommon.offsetA0) - fractal->transformCommon.offsetB0;
		tp = min(tp, d);
		if (tp == d) aux->color += fractal->foldColor.difs1;
	}
	// clip plane
	if (fractal->transformCommon.functionEnabledCFalse)
	{
		REAL e = fractal->transformCommon.offset4;
		REAL4 f = fabs(aux->const_c);
		f -= (REAL4){e, e, e, 0.0f};
		e = max(f.x, max(f.y, f.z));
		tp = max(tp, e);
	}
	aux->DE0 = tp;
	REAL colDist = aux->dist;
	aux->dist = min(aux->dist, aux->DE0 / (aux->DE + fractal->analyticDE.offset1));

	if (fractal->foldColor.auxColorEnabledFalse && aux->i >= fractal->foldColor.startIterationsA
			&& aux->i < fractal->foldColor.stopIterationsA)
	{
		if (colDist != aux->dist) aux->color += fractal->foldColor.difs0000.x;
	}
	return z;
}