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 * Formula based on Mandelbox (ABox). Extended to 4 dimensions and with variable scale parameter.
10 * This formula contains aux.color and aux.actualScale
11
12 * This file has been autogenerated by tools/populateUiInformation.php
13 * from the file "fractal_mandelbox_vary_scale4d.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 MandelboxVaryScale4dIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
18{
19	aux->actualScale =
20		fractal->mandelbox.scale + fractal->mandelboxVary4D.scaleVary * (fabs(aux->actualScale) - 1.0f);
21
22	REAL paraAddP0 = 0.0f;
23	if (fractal->Cpara.enabledParabFalse)
24	{ // parabolic = paraOffset + iter *slope + (iter *iter *scale)
25		paraAddP0 = fractal->Cpara.parabOffset0 + (aux->i * fractal->Cpara.parabSlope)
26								+ (aux->i * aux->i * 0.001f * fractal->Cpara.parabScale);
27		z.w += paraAddP0;
28	}
29
30	REAL4 oldZ = z;
31	z.x = fabs(z.x + fractal->mandelboxVary4D.fold) - fabs(z.x - fractal->mandelboxVary4D.fold) - z.x;
32	z.y = fabs(z.y + fractal->mandelboxVary4D.fold) - fabs(z.y - fractal->mandelboxVary4D.fold) - z.y;
33	z.z = fabs(z.z + fractal->mandelboxVary4D.fold) - fabs(z.z - fractal->mandelboxVary4D.fold) - z.z;
34	z.w = fabs(z.w + fractal->mandelboxVary4D.fold) - fabs(z.w - fractal->mandelboxVary4D.fold) - z.w;
35
36	if (z.x != oldZ.x) aux->color += fractal->mandelbox.color.factor4D.x;
37	if (z.y != oldZ.y) aux->color += fractal->mandelbox.color.factor4D.y;
38	if (z.z != oldZ.z) aux->color += fractal->mandelbox.color.factor4D.z;
39	if (z.w != oldZ.w) aux->color += fractal->mandelbox.color.factor4D.w;
40
41	REAL rr =
42		native_powr(z.x * z.x + z.y * z.y + z.z * z.z + z.w * z.w, fractal->mandelboxVary4D.rPower);
43	REAL m = aux->actualScale;
44	if (rr < fractal->mandelboxVary4D.minR * fractal->mandelboxVary4D.minR)
45	{
46		m = aux->actualScale / (fractal->mandelboxVary4D.minR * fractal->mandelboxVary4D.minR);
47		aux->color += fractal->mandelbox.color.factorSp1;
48	}
49	else if (rr < 1.0f)
50	{
51		m = aux->actualScale / rr;
52		aux->color += fractal->mandelbox.color.factorSp2;
53	}
54	z *= m;
55	aux->DE = aux->DE * fabs(m) + 1.0f;
56
57	// 6 plane rotation
58	if (fractal->transformCommon.functionEnabledRFalse
59			&& aux->i >= fractal->transformCommon.startIterationsR
60			&& aux->i < fractal->transformCommon.stopIterationsR)
61	{
62		REAL4 tp;
63		if (fractal->transformCommon.rotation44a.x != 0)
64		{
65			tp = z;
66			REAL alpha = fractal->transformCommon.rotation44a.x * M_PI_180_F;
67			z.x = tp.x * native_cos(alpha) + tp.y * native_sin(alpha);
68			z.y = tp.x * -native_sin(alpha) + tp.y * native_cos(alpha);
69		}
70		if (fractal->transformCommon.rotation44a.y != 0)
71		{
72			tp = z;
73			REAL beta = fractal->transformCommon.rotation44a.y * M_PI_180_F;
74			z.y = tp.y * native_cos(beta) + tp.z * native_sin(beta);
75			z.z = tp.y * -native_sin(beta) + tp.z * native_cos(beta);
76		}
77		if (fractal->transformCommon.rotation44a.z != 0)
78		{
79			tp = z;
80			REAL gamma = fractal->transformCommon.rotation44a.z * M_PI_180_F;
81			z.x = tp.x * native_cos(gamma) + tp.z * native_sin(gamma);
82			z.z = tp.x * -native_sin(gamma) + tp.z * native_cos(gamma);
83		}
84		if (fractal->transformCommon.rotation44b.x != 0)
85		{
86			tp = z;
87			REAL delta = fractal->transformCommon.rotation44b.x * M_PI_180_F;
88			z.x = tp.x * native_cos(delta) + tp.w * native_sin(delta);
89			z.w = tp.x * -native_sin(delta) + tp.w * native_cos(delta);
90		}
91		if (fractal->transformCommon.rotation44b.y != 0)
92		{
93			tp = z;
94			REAL epsilon = fractal->transformCommon.rotation44b.y * M_PI_180_F;
95			z.y = tp.y * native_cos(epsilon) + tp.w * native_sin(epsilon);
96			z.w = tp.y * -native_sin(epsilon) + tp.w * native_cos(epsilon);
97		}
98		if (fractal->transformCommon.rotation44b.z != 0)
99		{
100			tp = z;
101			REAL zeta = fractal->transformCommon.rotation44b.z * M_PI_180_F;
102			z.z = tp.z * native_cos(zeta) + tp.w * native_sin(zeta);
103			z.w = tp.z * -native_sin(zeta) + tp.w * native_cos(zeta);
104		}
105	}
106	return z;
107}