1/**
2 * Mandelbulber v2, a 3D fractal generator  _%}}i*<.        ____                _______
3 * Copyright (C) 2020 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 * Mandeltorus by Aexion
10 * @reference http://www.fractalforums.com/the-3d-mandelbulb/mandeldonuts/
11
12 * This file has been autogenerated by tools/populateUiInformation.php
13 * from the file "fractal_mandeltorus.cpp" in the folder formula/definition
14 * D O    N O T    E D I T    T H I S    F I L E !
15 */
16
17REAL4 MandeltorusIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
18{
19	if (fractal->transformCommon.functionEnabledFalse
20			&& aux->i >= fractal->transformCommon.startIterationsD
21			&& aux->i < fractal->transformCommon.stopIterationsD1) // pre-scale
22	{
23		z *= fractal->transformCommon.scale3D111;
24		aux->DE *= length(z) / aux->r;
25	}
26
27	REAL power1 = fractal->transformCommon.pwr8;	// Longitude power, symmetry
28	REAL power2 = fractal->transformCommon.pwr8a; // Latitude power
29
30	REAL rh = native_sqrt(z.x * z.x + z.z * z.z);
31
32	REAL phi = atan2(z.z, z.x);
33	REAL phipow = phi * power1;
34
35	REAL theta = atan2(rh, z.y);
36
37	REAL px = z.x - native_cos(phi) * 1.5f;
38	REAL pz = z.z - native_sin(phi) * 1.5f;
39	REAL rhrad = native_sqrt(px * px + pz * pz + z.y * z.y);
40	REAL rh1 = native_powr(rhrad, power2);
41	REAL rh2 = native_powr(rhrad, power1);
42
43	if (!fractal->transformCommon.functionEnabledzFalse) // mode 1
44	{
45		REAL thetapow = theta * power2;
46		REAL sintheta = native_sin(thetapow) * rh2;
47		z.x = sintheta * native_cos(phipow);
48		z.z = sintheta * native_sin(phipow);
49		z.y = native_cos(thetapow) * rh1; // mode 1
50	}
51	else // mode 2
52	{
53		REAL tangle = atan2(native_sqrt(px * px + pz * pz), z.y) * power2;
54		REAL sintheta = (1.5f + native_cos(tangle)) * rh2;
55		z.x = sintheta * native_cos(phipow);
56		z.z = sintheta * native_sin(phipow);
57		z.y = native_sin(tangle) * rh1; // mode 2
58	}
59
60	// DEcalc
61	REAL temp = rh2 * (power1 - fractal->analyticDE.offset2);
62	if (fractal->transformCommon.functionEnabledAyFalse)
63		temp = min(temp, rh1 * (power2 - fractal->analyticDE.offset2));
64
65	if (!fractal->analyticDE.enabledFalse)
66	{
67		aux->DE = temp * aux->DE + 1.0f;
68	}
69	else
70	{
71		aux->DE = temp * aux->DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset1;
72	}
73	return z;
74}