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 * BoxBulb power 2 V3  with scaling of z axis
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_fold_bulb_pow2_v3.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 BoxFoldBulbPow2V3Iteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
18{
19	// sphere inversion
20	if (fractal->transformCommon.sphereInversionEnabledFalse
21			&& aux->i >= fractal->transformCommon.startIterations
22			&& aux->i < fractal->transformCommon.stopIterations1)
23	{
24		REAL rr = 1.0f;
25		z += fractal->transformCommon.offset000;
26		rr = dot(z, z);
27		z *= fractal->transformCommon.scaleG1 / rr;
28		aux->DE *= (fractal->transformCommon.scaleG1 / rr);
29		z += fractal->transformCommon.additionConstant000 - fractal->transformCommon.offset000;
30		z *= fractal->transformCommon.scaleA1;
31		aux->DE *= fractal->transformCommon.scaleA1;
32	}
33
34	// REAL4 c = aux->const_c;
35	REAL colorAdd = 0.0f;
36	REAL rrCol = 0.0f;
37	REAL4 zCol = z;
38	REAL4 oldZ = z;
39
40	// tglad fold
41	if (aux->i >= fractal->transformCommon.startIterationsB
42			&& aux->i < fractal->transformCommon.stopIterationsB)
43	{
44		z.x = fabs(z.x + fractal->transformCommon.additionConstant111.x)
45					- fabs(z.x - fractal->transformCommon.additionConstant111.x) - z.x;
46		z.y = fabs(z.y + fractal->transformCommon.additionConstant111.y)
47					- fabs(z.y - fractal->transformCommon.additionConstant111.y) - z.y;
48		z.z = fabs(z.z + fractal->transformCommon.additionConstant111.z)
49					- fabs(z.z - fractal->transformCommon.additionConstant111.z) - z.z;
50		zCol = z;
51	}
52
53	// spherical fold
54	if (aux->i >= fractal->transformCommon.startIterationsS
55			&& aux->i < fractal->transformCommon.stopIterationsS)
56	{
57		REAL rr = dot(z, z);
58		rrCol = rr;
59		z += fractal->mandelbox.offset;
60
61		// if (r2 < 1e-21f) r2 = 1e-21f;
62		if (rr < fractal->transformCommon.minR2p25)
63		{
64			REAL tglad_factor1 = fractal->transformCommon.maxR2d1 / fractal->transformCommon.minR2p25;
65			z *= tglad_factor1;
66			aux->DE *= tglad_factor1;
67		}
68		else if (rr < fractal->transformCommon.maxR2d1)
69		{
70			REAL tglad_factor2 = fractal->transformCommon.maxR2d1 / rr;
71			z *= tglad_factor2;
72			aux->DE *= tglad_factor2;
73		}
74		z -= fractal->mandelbox.offset;
75	}
76	// scale
77	if (aux->i >= fractal->transformCommon.startIterationsC
78			&& aux->i < fractal->transformCommon.stopIterationsC)
79	{
80
81		REAL useScale = aux->actualScaleA + fractal->transformCommon.scale;
82
83		z *= useScale;
84		aux->DE = aux->DE * fabs(useScale);
85
86		if (aux->i >= fractal->transformCommon.startIterationsX
87				&& aux->i < fractal->transformCommon.stopIterationsX)
88		{
89			// update actualScale for next iteration
90			REAL vary = fractal->transformCommon.scaleVary0
91									* (fabs(aux->actualScaleA) - fractal->transformCommon.scaleB1);
92			if (fractal->transformCommon.functionEnabledMFalse)
93				aux->actualScaleA = -vary;
94			else
95				aux->actualScaleA = aux->actualScaleA - vary;
96		}
97	}
98
99	if (fractal->transformCommon.functionEnabledXFalse
100			&& aux->i >= fractal->transformCommon.startIterationsTM
101			&& aux->i < fractal->transformCommon.stopIterationsTM1)
102	{
103		REAL tempXZ = z.x * SQRT_2_3_F - z.z * SQRT_1_3_F;
104		z = (REAL4){(tempXZ - z.y) * SQRT_1_2_F, (tempXZ + z.y) * SQRT_1_2_F,
105			z.x * SQRT_1_3_F + z.z * SQRT_2_3_F, z.w};
106		REAL4 temp = z;
107		REAL tempL = length(temp);
108		z = fabs(z) * fractal->transformCommon.scale3D333;
109		// if (tempL < 1e-21f) tempL = 1e-21f;
110		REAL avgScale = length(z) / tempL;
111		aux->DE = aux->DE * avgScale;
112		z = (fabs(z + fractal->transformCommon.additionConstantA111)
113				 - fabs(z - fractal->transformCommon.additionConstantA111) - z);
114		tempXZ = (z.y + z.x) * SQRT_1_2_F;
115		z = (REAL4){z.z * SQRT_1_3_F + tempXZ * SQRT_2_3_F, (z.y - z.x) * SQRT_1_2_F,
116			z.z * SQRT_2_3_F - tempXZ * SQRT_1_3_F, z.w};
117	}
118
119	// octo
120	if (fractal->transformCommon.functionEnabledDFalse
121			&& aux->i >= fractal->transformCommon.startIterationsD
122			&& aux->i < fractal->transformCommon.stopIterationsD)
123
124	{
125		if (z.x + z.y < 0.0f) z = (REAL4){-z.y, -z.x, z.z, z.w};
126
127		if (z.x + z.z < 0.0f) // z.xz = -z.zx;
128			z = (REAL4){-z.z, z.y, -z.x, z.w};
129
130		if (z.x - z.y < 0.0f) // z.xy = z.yx;
131			z = (REAL4){z.y, z.x, z.z, z.w};
132
133		if (z.x - z.z < 0.0f) // z.xz = z.zx;
134			z = (REAL4){z.z, z.y, z.x, z.w};
135
136		z.x = fabs(z.x);
137		z = z * fractal->transformCommon.scaleA2
138				- fractal->transformCommon.offset100 * (fractal->transformCommon.scaleA2 - 1.0f);
139		aux->DE *= fabs(fractal->transformCommon.scaleA2);
140	}
141
142	if (fractal->transformCommon.functionEnabledRFalse
143			&& aux->i >= fractal->transformCommon.startIterationsR
144			&& aux->i < fractal->transformCommon.stopIterationsR)
145		z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, z);
146
147	if (fractal->transformCommon.functionEnabledFFalse
148			&& aux->i >= fractal->transformCommon.startIterationsM
149			&& aux->i < fractal->transformCommon.stopIterationsM)
150	{ // fabs() and menger fold
151		z = fabs(z + fractal->transformCommon.additionConstantA000);
152		if (z.x - z.y < 0.0f)
153		{
154			REAL temp = z.y;
155			z.y = z.x;
156			z.x = temp;
157		}
158		if (z.x - z.z < 0.0f)
159		{
160			REAL temp = z.z;
161			z.z = z.x;
162			z.x = temp;
163		}
164		if (z.y - z.z < 0.0f)
165		{
166			REAL temp = z.z;
167			z.z = z.y;
168			z.y = temp;
169		}
170		// menger scales and offsets
171		z *= fractal->transformCommon.scale3;
172		z.x -= 2.0f * fractal->transformCommon.constantMultiplier111.x;
173		z.y -= 2.0f * fractal->transformCommon.constantMultiplier111.y;
174		if (fractal->transformCommon.functionEnabled)
175		{
176			if (z.z > 1.0f) z.z -= 2.0f * fractal->transformCommon.constantMultiplier111.z;
177		}
178		else
179		{
180			z.z -= 2.0f * fractal->transformCommon.constantMultiplier111.z;
181		}
182		aux->DE *= fractal->transformCommon.scale3;
183	}
184
185	if (aux->i >= fractal->transformCommon.startIterationsA
186			&& aux->i < fractal->transformCommon.stopIterationsA)
187	{
188		aux->r = length(z);
189
190		if (fractal->analyticDE.enabledFalse)
191		{
192			aux->DE = aux->r * aux->DE * 10.0f * fractal->analyticDE.scale1
193									* native_sqrt(fractal->foldingIntPow.zFactor * fractal->foldingIntPow.zFactor
194																+ 2.0f + fractal->analyticDE.offset2)
195								+ fractal->analyticDE.offset1;
196		}
197		else
198		{
199			aux->DE = aux->r * aux->DE * 16.0f * fractal->analyticDE.scale1
200									* native_sqrt(fractal->foldingIntPow.zFactor * fractal->foldingIntPow.zFactor
201																+ 2.0f + fractal->analyticDE.offset2)
202									/ SQRT_3_F
203								+ fractal->analyticDE.offset1;
204		}
205
206		z *= 2.0f;
207		REAL x2 = z.x * z.x;
208		REAL y2 = z.y * z.y;
209		REAL z2 = z.z * z.z;
210		REAL temp = 1.0f - z2 / (x2 + y2);
211		REAL4 zTemp;
212		zTemp.x = (x2 - y2) * temp;
213		zTemp.y = 2.0f * z.x * z.y * temp;
214		zTemp.z = -2.0f * z.z * native_sqrt(x2 + y2);
215		zTemp.w = z.w;
216		z = zTemp;
217		z.z *= fractal->foldingIntPow.zFactor;
218	}
219	if (fractal->foldColor.auxColorEnabledFalse)
220	{
221		if (zCol.x != oldZ.x)
222			colorAdd += fractal->mandelbox.color.factor.x
223									* (fabs(zCol.x) - fractal->transformCommon.additionConstant111.x);
224		if (zCol.y != oldZ.y)
225			colorAdd += fractal->mandelbox.color.factor.y
226									* (fabs(zCol.y) - fractal->transformCommon.additionConstant111.y);
227		if (zCol.z != oldZ.z)
228			colorAdd += fractal->mandelbox.color.factor.z
229									* (fabs(zCol.z) - fractal->transformCommon.additionConstant111.z);
230
231		if (rrCol < fractal->transformCommon.maxR2d1)
232		{
233			if (rrCol < fractal->transformCommon.minR2p25)
234				colorAdd += fractal->mandelbox.color.factorSp1 * (fractal->transformCommon.minR2p25 - rrCol)
235										+ fractal->mandelbox.color.factorSp2
236												* (fractal->transformCommon.maxR2d1 - fractal->transformCommon.minR2p25);
237			else
238				colorAdd += fractal->mandelbox.color.factorSp2 * (fractal->transformCommon.maxR2d1 - rrCol);
239		}
240
241		aux->color += colorAdd;
242	}
243	return z;
244}