/**
 * Mandelbulber v2, a 3D fractal generator  _%}}i*<.        ____                _______
 * Copyright (C) 2020 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%+++
 *
 * Menger Cross KIFS
 * from code by Knighty
 * http://www.fractalforums.com/fragmentarium/
 * cross-menger!-can-anyone-do-this/msg93972/#new

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

REAL4 MengerCrossKIFSIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
{
	REAL4 gap = fractal->transformCommon.constantMultiplier000;
	REAL t;
	REAL dot1;
	if (fractal->transformCommon.functionEnabledFalse
			&& aux->i >= fractal->transformCommon.startIterations
			&& aux->i < fractal->transformCommon.stopIterations1)
	{
		z.y = fabs(z.y);
		z.z = fabs(z.z);
		if (fractal->transformCommon.functionEnabledFFalse) z.x = fabs(z.x);

		dot1 = (z.x * -SQRT_3_4_F + z.y * 0.5f) * fractal->transformCommon.scale;
		t = max(0.0f, dot1);
		z.x -= (t * -SQRT_3_F) - 0.5f;
		z.y = fabs(z.y - t);

		if (z.y > z.z)
		{
			REAL temp = z.y;
			z.y = z.z;
			z.z = temp;
		}
		z.y -= 0.75f;
		z -= gap * (REAL4){SQRT_3_4_F, 1.5f, 1.5f, 0.0f};

		if (z.z > z.x)
		{
			REAL temp = z.z;
			z.z = z.x;
			z.x = temp;
		}

		z *= fractal->transformCommon.constantMultiplier111; // post scale

		if (fractal->transformCommon.functionEnabledyFalse)
		{
			z.y = max(0.0f, z.y) * fractal->transformCommon.scaleA1;
			z.z = max(0.0f, z.z) * fractal->transformCommon.scaleB1;
		}

		z += fractal->transformCommon.additionConstant000; // post offset
		z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, z);

		aux->DE *= fractal->analyticDE.scale1; // tweak
	}

	if (fractal->transformCommon.functionEnabled
			&& aux->i >= fractal->transformCommon.startIterationsA
			&& aux->i < fractal->transformCommon.stopIterationsA)
	{ // CrossMengerKIFS
		REAL lengthL;
		// z = ( z );//+ preAdd );
		z.y = fabs(z.y);
		z.z = fabs(z.z);
		if (fractal->transformCommon.functionEnabledzFalse) z.x = fabs(z.x);

		lengthL = z.x * SQRT_3_4_F - z.y * 0.5f;
		if (lengthL < 0.0f)
		{
			z.x -= SQRT_3_4_F * (2.0f * lengthL);
			z.y -= -lengthL;
		}
		lengthL = z.y;
		if (lengthL < 0.0f)
		{
			z.y -= 2.0f * lengthL;
		}
		lengthL = (-z.y + z.z) * SQRT_1_2_F;
		if (lengthL < 0.0f)
		{
			z.y -= -SQRT_1_2_F * (2.0f * lengthL);
			z.z -= SQRT_1_2_F * (2.0f * lengthL);
		}
		lengthL = z.y;
		if (lengthL < 0.5f)
		{
			z.y -= 2.0f * (lengthL - 0.5f);
		}
		REAL4 edge = fractal->transformCommon.offset222;
		if (fractal->transformCommon.functionEnabledxFalse)
		{
			z.x = edge.x - z.x;
			z.y = edge.y - z.y;
			z.z = edge.z - z.z;
		}

		z *= fractal->transformCommon.scale3;
		z -= (REAL4){SQRT_3_4_F, 1.5f, 1.5f, 0.0f} * (fractal->transformCommon.scale3 - 1.0f);
		aux->DE *= fractal->transformCommon.scale3;

		z += fractal->transformCommon.offset000; // post offset
		if (fractal->transformCommon.functionEnabledPFalse)
		{
			z.x = fabs(z.x + fractal->transformCommon.offset) + fractal->transformCommon.offset0;
		}
		if (fractal->transformCommon.functionEnabledRFalse
				&& aux->i >= fractal->transformCommon.startIterationsR
				&& aux->i < fractal->transformCommon.stopIterationsR)
		{
			z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix2, z);
		}
	}
	return z;
}