1/**
2 * Mandelbulber v2, a 3D fractal generator  _%}}i*<.        ____                _______
3 * Copyright (C) 2021 Mandelbulber Team   _>]|=||i=i<,     / __ \___  ___ ___  / ___/ /
4 *                                        \><||i|=>>%)    / /_/ / _ \/ -_) _ \/ /__/ /__
5 * This file is part of Mandelbulber.     )<=i=]=|=i<>    \____/ .__/\__/_//_/\___/____/
6 * The project is licensed under GPLv3,   -<>>=|><|||`        /_/
7 * see also COPYING file in this folder.    ~+{i%+++
8 *
9 * https://nylander.wordpress.com/2009/07/03/3d-mandelbrot-set-2/
10 * Found on http://bugman123.com/Hypercomplex/index.html
11 * Quadratic 3D Mandelbulb set, based on D. White's new "triplex squaring formula".
12 * Hyperbolic radius added by Darkbeam refer Quadrat3D in M3D
13
14 * This file has been autogenerated by tools/populateUiInformation.php
15 * from the file "fractal_mandelbulb_quadrat.cpp" in the folder formula/definition
16 * D O    N O T    E D I T    T H I S    F I L E !
17 */
18
19REAL4 MandelbulbQuadratIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
20{
21	if (fractal->transformCommon.functionEnabledAFalse)
22	{
23		if (fractal->transformCommon.functionEnabledAxFalse) z.x = fabs(z.x);
24		if (fractal->transformCommon.functionEnabledAyFalse) z.y = fabs(z.y);
25		if (fractal->transformCommon.functionEnabledAzFalse) z.z = fabs(z.z);
26	}
27
28	if (fractal->transformCommon.functionEnabled)
29	{
30		aux->DE = aux->DE * 2.0f * length(z) + 1.0f;
31		REAL temp = 0.0f;
32		if (fractal->transformCommon.functionEnabledDFalse
33				&& aux->i >= fractal->transformCommon.startIterationsD
34				&& aux->i < fractal->transformCommon.stopIterationsD1)
35			temp = fractal->transformCommon.offset0;
36
37		temp = z.x * z.x + z.y * z.y + temp;
38		if (temp == 0.0f)
39			z = aux->const_c;
40		else if (temp < 0.0f)
41			z = (REAL4){0.0f, 0.0f, 0.0f, 0.0f};
42		else
43		{
44			REAL4 Mul = fractal->transformCommon.constantMultiplier122;
45			Mul.w = 0.0f;
46			REAL ZR = fractal->transformCommon.offset1;
47			Mul.z = -Mul.z * z.z * native_sqrt(temp);
48			temp = ZR - z.z * z.z / temp;
49			Mul.x = Mul.x * (z.x * z.x - z.y * z.y) * temp;
50			Mul.y = Mul.y * z.x * z.y * temp;
51			z = Mul;
52
53			// offset (Julia)
54			z += fractal->transformCommon.additionConstant000;
55		}
56	}
57
58	if (fractal->transformCommon.functionEnabledFalse)
59	{
60		aux->DE = aux->DE * 2.0f * length(z) + 1.0f;
61
62		REAL temp = 0.0f;
63		if (fractal->transformCommon.functionEnabledTFalse
64				&& aux->i >= fractal->transformCommon.startIterationsT
65				&& aux->i < fractal->transformCommon.stopIterationsT1)
66			temp = fractal->transformCommon.offsetA0;
67
68		temp = z.z * z.z + z.y * z.y + temp;
69		if (temp == 0.0f)
70			z = aux->const_c;
71		else if (temp < 0.0f)
72			z = (REAL4){0.0f, 0.0f, 0.0f, 0.0f};
73		else
74		{
75			REAL4 Mul = fractal->transformCommon.constantMultiplier221;
76			Mul.w = 0.0f;
77			REAL ZR = fractal->transformCommon.offsetA1;
78			Mul.x = -Mul.x * z.x * native_sqrt(temp);
79			temp = ZR - z.x * z.x / temp;
80			Mul.z = Mul.z * (z.z * z.z - z.y * z.y) * temp;
81			Mul.y = Mul.y * z.z * z.y * temp;
82			z = Mul;
83
84			// offset (Julia)
85			z += fractal->transformCommon.additionConstantA000;
86		}
87	}
88
89	z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, z);
90
91	// DE tweak
92	if (fractal->analyticDE.enabledFalse)
93		aux->DE = aux->DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
94	return z;
95}