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 * boxFold4dBulb.
10 * This formula contains aux.color and aux.actualScaleA
11
12 * This file has been autogenerated by tools/populateUiInformation.php
13 * from the file "fractal_box_fold4d_bulb_pow2.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 BoxFold4dBulbPow2Iteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
18{
19	REAL colorAdd = 0.0f;
20	REAL rrCol = 0.0f;
21	REAL4 zCol = z;
22	REAL4 oldZ = z;
23
24	// parabolic.w = paraOffset + iter *slope + (iter *iter *scale)
25	REAL paraAddP0 = 0.0f;
26	if (fractal->Cpara.enabledParabFalse)
27	{
28		REAL parabScale = 0.0f;
29		if (fractal->Cpara.parabScale != 0.0f)
30			parabScale = aux->i * aux->i * 0.001f * fractal->Cpara.parabScale;
31		paraAddP0 = fractal->Cpara.parabOffset0 + (aux->i * fractal->Cpara.parabSlope) + (parabScale);
32		z.w += paraAddP0;
33	}
34
35	// sinusoidal w
36	REAL sinAdd = 0.0f;
37	if (fractal->transformCommon.functionEnabledDFalse)
38	{
39		sinAdd =
40			native_sin((aux->i + fractal->transformCommon.offset0) / fractal->transformCommon.scaleA1)
41			* fractal->transformCommon.scaleC1;
42		z.w += sinAdd;
43	}
44
45	if (aux->i >= fractal->transformCommon.startIterationsB
46			&& aux->i < fractal->transformCommon.stopIterationsB)
47	{
48		oldZ = z;
49		z.x = fabs(z.x + fractal->transformCommon.offset1111.x)
50					- fabs(z.x - fractal->transformCommon.offset1111.x) - z.x;
51		z.y = fabs(z.y + fractal->transformCommon.offset1111.y)
52					- fabs(z.y - fractal->transformCommon.offset1111.y) - z.y;
53		z.z = fabs(z.z + fractal->transformCommon.offset1111.z)
54					- fabs(z.z - fractal->transformCommon.offset1111.z) - z.z;
55		z.w = fabs(z.w + fractal->transformCommon.offset1111.w)
56					- fabs(z.w - fractal->transformCommon.offset1111.w) - z.w;
57		zCol = z;
58	}
59
60	// sph fold
61	if (aux->i >= fractal->transformCommon.startIterationsS
62			&& aux->i < fractal->transformCommon.stopIterationsS)
63	{
64		REAL rr = dot(z, z);
65
66		// r power
67		if (fractal->mandelboxVary4D.rPower != 1.0f)
68			rr = native_powr(rr, fractal->mandelboxVary4D.rPower);
69		rrCol = rr;
70		// spherical fold
71		z += fractal->transformCommon.offset0000;
72		if (rr < fractal->transformCommon.minR2p25)
73		{
74			z *= fractal->transformCommon.maxMinR2factor;
75			aux->DE *= fractal->transformCommon.maxMinR2factor;
76		}
77		else if (rr < fractal->transformCommon.maxR2d1)
78		{
79			z *= fractal->transformCommon.maxR2d1 / rr;
80			aux->DE *= fractal->transformCommon.maxR2d1 / rr;
81		}
82
83		z -= fractal->transformCommon.offset0000;
84	}
85
86	// scale
87	REAL useScale = 1.0f;
88	if (aux->i >= fractal->transformCommon.startIterationsC
89			&& aux->i < fractal->transformCommon.stopIterationsC)
90	{
91
92		useScale = aux->actualScaleA + fractal->transformCommon.scale;
93
94		z *= useScale;
95		aux->DE = aux->DE * fabs(useScale);
96
97		if (fractal->transformCommon.functionEnabledSFalse
98				&& aux->i >= fractal->transformCommon.startIterationsX
99				&& aux->i < fractal->transformCommon.stopIterationsX)
100		{
101			// update actualScale for next iteration
102			REAL vary = fractal->transformCommon.scaleVary0
103									* (fabs(aux->actualScaleA) - fractal->transformCommon.scaleB1);
104			if (fractal->transformCommon.functionEnabledMFalse)
105				aux->actualScaleA = -vary;
106			else
107				aux->actualScaleA = aux->actualScaleA - vary;
108		}
109	}
110
111	// 6 plane rotation
112	if (fractal->transformCommon.functionEnabledRFalse
113			&& aux->i >= fractal->transformCommon.startIterationsR
114			&& aux->i < fractal->transformCommon.stopIterationsR)
115	{
116		REAL4 tp;
117		if (fractal->transformCommon.rotation44a.x != 0)
118		{
119			tp = z;
120			REAL alpha = fractal->transformCommon.rotation44a.x * M_PI_180_F;
121			z.x = tp.x * native_cos(alpha) + tp.y * native_sin(alpha);
122			z.y = tp.x * -native_sin(alpha) + tp.y * native_cos(alpha);
123		}
124		if (fractal->transformCommon.rotation44a.y != 0)
125		{
126			tp = z;
127			REAL beta = fractal->transformCommon.rotation44a.y * M_PI_180_F;
128			z.y = tp.y * native_cos(beta) + tp.z * native_sin(beta);
129			z.z = tp.y * -native_sin(beta) + tp.z * native_cos(beta);
130		}
131		if (fractal->transformCommon.rotation44a.z != 0)
132		{
133			tp = z;
134			REAL gamma = fractal->transformCommon.rotation44a.z * M_PI_180_F;
135			z.x = tp.x * native_cos(gamma) + tp.z * native_sin(gamma);
136			z.z = tp.x * -native_sin(gamma) + tp.z * native_cos(gamma);
137		}
138		if (fractal->transformCommon.rotation44b.x != 0)
139		{
140			tp = z;
141			REAL delta = fractal->transformCommon.rotation44b.x * M_PI_180_F;
142			z.x = tp.x * native_cos(delta) + tp.w * native_sin(delta);
143			z.w = tp.x * -native_sin(delta) + tp.w * native_cos(delta);
144		}
145		if (fractal->transformCommon.rotation44b.y != 0)
146		{
147			tp = z;
148			REAL epsilon = fractal->transformCommon.rotation44b.y * M_PI_180_F;
149			z.y = tp.y * native_cos(epsilon) + tp.w * native_sin(epsilon);
150			z.w = tp.y * -native_sin(epsilon) + tp.w * native_cos(epsilon);
151		}
152		if (fractal->transformCommon.rotation44b.z != 0)
153		{
154			tp = z;
155			REAL zeta = fractal->transformCommon.rotation44b.z * M_PI_180_F;
156			z.z = tp.z * native_cos(zeta) + tp.w * native_sin(zeta);
157			z.w = tp.z * -native_sin(zeta) + tp.w * native_cos(zeta);
158		}
159	}
160	// offset
161	z += fractal->transformCommon.additionConstant0000;
162
163	// bulb pow2
164	if (aux->i >= fractal->transformCommon.startIterationsA
165			&& aux->i < fractal->transformCommon.stopIterationsA)
166	{
167		aux->r = length(z);
168		aux->DE = aux->r * aux->DE * 16.0f * fractal->analyticDE.scale1
169								* native_sqrt(fractal->foldingIntPow.zFactor * fractal->foldingIntPow.zFactor + 2.0f
170															+ fractal->analyticDE.offset2)
171								/ SQRT_3_F
172							+ fractal->analyticDE.offset1;
173
174		z = z * 2.0f;
175		REAL x2 = z.x * z.x;
176		REAL y2 = z.y * z.y;
177		REAL z2 = z.z * z.z;
178		REAL temp = 1.0f - z2 / (x2 + y2);
179		REAL4 zTemp;
180		zTemp.x = (x2 - y2) * temp;
181		zTemp.y = 2.0f * z.x * z.y * temp;
182		zTemp.z = -2.0f * z.z * native_sqrt(x2 + y2);
183		zTemp.w = z.w;
184		z = zTemp;
185		z.z *= fractal->foldingIntPow.zFactor;
186	}
187
188	// color
189	if (fractal->foldColor.auxColorEnabledFalse)
190	{
191		if (fractal->transformCommon.functionEnabledCxFalse)
192		{
193			if (zCol.x != oldZ.x)
194				colorAdd +=
195					fractal->mandelbox.color.factor.x * (fabs(zCol.x) - fractal->mandelbox.color.factor4D.x);
196			if (zCol.y != oldZ.y)
197				colorAdd +=
198					fractal->mandelbox.color.factor.y * (fabs(zCol.y) - fractal->mandelbox.color.factor4D.y);
199			if (zCol.z != oldZ.z)
200				colorAdd +=
201					fractal->mandelbox.color.factor.z * (fabs(zCol.z) - fractal->mandelbox.color.factor4D.z);
202			if (zCol.w != oldZ.w)
203				colorAdd +=
204					fractal->mandelbox.color.factor.z * (fabs(zCol.w) - fractal->mandelbox.color.factor4D.w);
205			if (rrCol < fractal->transformCommon.maxR2d1)
206			{
207				if (rrCol < fractal->transformCommon.minR2p25)
208					colorAdd +=
209						fractal->mandelbox.color.factorSp1 * (fractal->transformCommon.minR2p25 - rrCol)
210						+ fractal->mandelbox.color.factorSp2
211								* (fractal->transformCommon.maxR2d1 - fractal->transformCommon.minR2p25);
212				else
213					colorAdd +=
214						fractal->mandelbox.color.factorSp2 * (fractal->transformCommon.maxR2d1 - rrCol);
215			}
216		}
217		else
218		{
219			if (zCol.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor4D.x;
220			if (zCol.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor4D.y;
221			if (zCol.z != oldZ.z) colorAdd += fractal->mandelbox.color.factor4D.z;
222			if (zCol.w != oldZ.w) colorAdd += fractal->mandelbox.color.factor4D.w;
223			if (rrCol < fractal->transformCommon.minR2p25)
224				colorAdd += fractal->mandelbox.color.factorSp1;
225			else if (rrCol < fractal->transformCommon.maxR2d1)
226				colorAdd += fractal->mandelbox.color.factorSp2;
227		}
228		aux->color += colorAdd;
229	}
230	return z;
231}