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 * DifsEllipsoidIteration  fragmentarium code, mdifs by knighty (jan 2012)
10 * and http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
11
12 * This file has been autogenerated by tools/populateUiInformation.php
13 * from the file "fractal_difs_ellipsoid.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 DIFSEllipsoidIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux)
18{
19	REAL colorAdd = 0.0f;
20	REAL4 oldZ = z;
21	REAL4 boxFold = fractal->transformCommon.additionConstantA111;
22
23	// abs z
24	if (fractal->transformCommon.functionEnabledAx
25			&& aux->i >= fractal->transformCommon.startIterationsX
26			&& aux->i < fractal->transformCommon.stopIterationsX)
27		z.x = fabs(z.x);
28	if (fractal->transformCommon.functionEnabledAy
29			&& aux->i >= fractal->transformCommon.startIterationsY
30			&& aux->i < fractal->transformCommon.stopIterationsY)
31		z.y = fabs(z.y);
32	if (fractal->transformCommon.functionEnabledAzFalse
33			&& aux->i >= fractal->transformCommon.startIterationsZ
34			&& aux->i < fractal->transformCommon.stopIterationsZ)
35		z.z = fabs(z.z);
36	// folds
37	if (fractal->transformCommon.functionEnabledFalse)
38	{
39		// xy box fold
40		if (fractal->transformCommon.functionEnabledBxFalse
41				&& aux->i >= fractal->transformCommon.startIterationsA
42				&& aux->i < fractal->transformCommon.stopIterationsA)
43		{
44			z.x -= boxFold.x;
45			z.y -= boxFold.y;
46		}
47		// xyz box fold
48		if (fractal->transformCommon.functionEnabledByFalse
49				&& aux->i >= fractal->transformCommon.startIterationsB
50				&& aux->i < fractal->transformCommon.stopIterationsB)
51			z -= boxFold;
52		// polyfold
53		if (fractal->transformCommon.functionEnabledPFalse
54				&& aux->i >= fractal->transformCommon.startIterationsP
55				&& aux->i < fractal->transformCommon.stopIterationsP)
56		{
57			z.x = fabs(z.x);
58			REAL psi = M_PI_F / fractal->transformCommon.int6;
59			psi = fabs(fmod(atan2(z.y, z.x) + psi, 2.0f * psi) - psi);
60			REAL len = native_sqrt(z.x * z.x + z.y * z.y);
61			z.x = native_cos(psi) * len;
62			z.y = native_sin(psi) * len;
63		}
64		// diag fold1
65		if (fractal->transformCommon.functionEnabledCxFalse
66				&& aux->i >= fractal->transformCommon.startIterationsCx
67				&& aux->i < fractal->transformCommon.stopIterationsCx)
68			if (z.x > z.y)
69			{
70				REAL temp = z.x;
71				z.x = z.y;
72				z.y = temp;
73			}
74		// abs offsets
75		if (fractal->transformCommon.functionEnabledCFalse
76				&& aux->i >= fractal->transformCommon.startIterationsC
77				&& aux->i < fractal->transformCommon.stopIterationsC)
78		{
79			REAL xOffset = fractal->transformCommon.offsetC0;
80			if (z.x < xOffset) z.x = fabs(z.x - xOffset) + xOffset;
81		}
82		if (fractal->transformCommon.functionEnabledDFalse
83				&& aux->i >= fractal->transformCommon.startIterationsD
84				&& aux->i < fractal->transformCommon.stopIterationsD)
85		{
86			REAL yOffset = fractal->transformCommon.offsetD0;
87			if (z.y < yOffset) z.y = fabs(z.y - yOffset) + yOffset;
88		}
89		// diag fold2
90		if (fractal->transformCommon.functionEnabledCyFalse
91				&& aux->i >= fractal->transformCommon.startIterationsCy
92				&& aux->i < fractal->transformCommon.stopIterationsCy)
93			if (z.x > z.y)
94			{
95				REAL temp = z.x;
96				z.x = z.y;
97				z.y = temp;
98			}
99	}
100
101	// reverse offset part 1
102	if (aux->i >= fractal->transformCommon.startIterationsE
103			&& aux->i < fractal->transformCommon.stopIterationsE)
104		z.x -= fractal->transformCommon.offsetE2;
105
106	if (aux->i >= fractal->transformCommon.startIterationsF
107			&& aux->i < fractal->transformCommon.stopIterationsF)
108		z.y -= fractal->transformCommon.offsetF2;
109
110	// scale
111	REAL useScale = 1.0f;
112	if (aux->i >= fractal->transformCommon.startIterationsS
113			&& aux->i < fractal->transformCommon.stopIterationsS)
114	{
115		useScale = aux->actualScaleA + fractal->transformCommon.scale2;
116		z *= useScale;
117		aux->DE = aux->DE * fabs(useScale) + 1.0f;
118		// scale vary
119		if (fractal->transformCommon.functionEnabledKFalse
120				&& aux->i >= fractal->transformCommon.startIterationsK
121				&& aux->i < fractal->transformCommon.stopIterationsK)
122		{
123			// update actualScaleA for next iteration
124			REAL vary = fractal->transformCommon.scaleVary0
125									* (fabs(aux->actualScaleA) - fractal->transformCommon.scaleC1);
126			aux->actualScaleA -= vary;
127		}
128	}
129
130	// reverse offset part 2
131	if (aux->i >= fractal->transformCommon.startIterationsE
132			&& aux->i < fractal->transformCommon.stopIterationsE)
133		z.x += fractal->transformCommon.offsetE2;
134
135	if (aux->i >= fractal->transformCommon.startIterationsF
136			&& aux->i < fractal->transformCommon.stopIterationsF)
137		z.y += fractal->transformCommon.offsetF2;
138
139	// offset
140	z += fractal->transformCommon.offset001;
141
142	// rotation
143	if (fractal->transformCommon.functionEnabledRFalse
144			&& aux->i >= fractal->transformCommon.startIterationsR
145			&& aux->i < fractal->transformCommon.stopIterationsR)
146	{
147		z = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, z);
148	}
149
150	// DE
151	REAL colorDist = aux->dist;
152	REAL4 zc = oldZ;
153
154	// ellipsoid
155	if (aux->i >= fractal->transformCommon.startIterations
156			&& aux->i < fractal->transformCommon.stopIterations)
157	{
158		REAL4 rads4 = fractal->transformCommon.additionConstant111;
159		REAL3 rads3 = (REAL3){rads4.x, rads4.y, rads4.z};
160		REAL tempX = zc.x;
161		REAL tempY = zc.y;
162		REAL tempZ = zc.z;
163		REAL absZ = fabs(zc.z);
164
165		if (fractal->transformCommon.functionEnabledJFalse) absZ = zc.z;
166
167		if (fractal->transformCommon.functionEnabledNFalse
168				&& aux->i >= fractal->transformCommon.startIterationsN
169				&& aux->i < fractal->transformCommon.stopIterationsN)
170		{
171			tempX = zc.x + absZ * fractal->transformCommon.scale0;
172		}
173		if (fractal->transformCommon.functionEnabledOFalse
174				&& aux->i >= fractal->transformCommon.startIterationsO
175				&& aux->i < fractal->transformCommon.stopIterationsO)
176		{
177			tempY = zc.y + absZ * fractal->transformCommon.scaleA0;
178		}
179
180		// z.z sqrd
181		if (fractal->transformCommon.functionEnabledTFalse
182				&& aux->i >= fractal->transformCommon.startIterationsT
183				&& aux->i < fractal->transformCommon.stopIterationsT)
184		{
185			tempZ = zc.z * zc.z;
186		}
187
188		REAL3 rV = (REAL3){tempX, tempY, tempZ};
189		rV /= rads3;
190
191		REAL3 rrV = rV;
192		rrV /= rads3;
193
194		REAL rd = length(rV);
195		REAL rrd = length(rrV);
196		REAL ellD = rd * (rd - 1.0f) / rrd;
197		aux->dist = min(aux->dist, ellD / aux->DE);
198	}
199	// sphere
200	if (fractal->transformCommon.functionEnabledMFalse
201			&& aux->i >= fractal->transformCommon.startIterationsM
202			&& aux->i < fractal->transformCommon.stopIterationsM)
203	{
204		REAL spD = length(zc) - fractal->transformCommon.offsetR1;
205		aux->dist = min(aux->dist, spD / aux->DE);
206	}
207	// aux->color
208	if (fractal->foldColor.auxColorEnabled)
209	{
210		if (fractal->foldColor.auxColorEnabledFalse)
211		{
212			colorAdd += fractal->foldColor.difs0000.x * fabs(z.x * z.y);
213			colorAdd += fractal->foldColor.difs0000.y * max(z.x, z.y);
214		}
215		colorAdd += fractal->foldColor.difs1;
216		if (fractal->foldColor.auxColorEnabledA)
217		{
218			if (colorDist != aux->dist) aux->color += colorAdd;
219		}
220		else
221			aux->color += colorAdd;
222	}
223	return z;
224}