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 * Mandelbox Menger Sponge Hybrid
10 * @reference
11 * http://www.fractalforums.com/ifs-iterated-function-systems/amazing-fractal/msg12467/#msg12467
12 * This formula contains aux.color
13 */
14
15 #include "all_fractal_definitions.h"
16
cFractalMandelboxMenger()17 cFractalMandelboxMenger::cFractalMandelboxMenger() : cAbstractFractal()
18 {
19 nameInComboBox = "Mandelbox - Menger";
20 internalName = "mandelbox_menger";
21 internalID = fractal::mandelboxMenger;
22 DEType = analyticDEType;
23 DEFunctionType = linearDEFunction;
24 cpixelAddition = cpixelEnabledByDefault;
25 defaultBailout = 100.0;
26 DEAnalyticFunction = analyticFunctionLinear;
27 coloringFunction = coloringFunctionABox;
28 }
29
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)30 void cFractalMandelboxMenger::FormulaCode(CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
31 {
32 CVector4 c = aux.const_c;
33 double colorAdd = 0.0;
34 if (fractal->mandelbox.rotationsEnabled)
35 {
36 CVector4 zRot;
37 // cast vector to array pointer for address taking of components in opencl
38 double *zRotP = (double *)&zRot;
39 const double *colP = (const double *)&fractal->mandelbox.color.factor;
40 for (int dim = 0; dim < 3; dim++)
41 {
42 // handle each dimension x, y and z sequentially in pointer var dim
43 double *rotDim = (dim == 0) ? &zRotP[0] : ((dim == 1) ? &zRotP[1] : &zRotP[2]);
44 const double *colorFactor = (dim == 0) ? &colP[0] : ((dim == 1) ? &colP[1] : &colP[2]);
45
46 zRot = fractal->mandelbox.rot[0][dim].RotateVector(z);
47 if (*rotDim > fractal->mandelbox.foldingLimit)
48 {
49 *rotDim = fractal->mandelbox.foldingValue - *rotDim;
50 z = fractal->mandelbox.rotinv[0][dim].RotateVector(zRot);
51 colorAdd += *colorFactor;
52 }
53 else
54 {
55 zRot = fractal->mandelbox.rot[1][dim].RotateVector(z);
56 if (*rotDim < -fractal->mandelbox.foldingLimit)
57 {
58 *rotDim = -fractal->mandelbox.foldingValue - *rotDim;
59 z = fractal->mandelbox.rotinv[1][dim].RotateVector(zRot);
60 colorAdd += *colorFactor;
61 }
62 }
63 }
64 }
65 else
66 {
67 if (aux.i >= fractal->transformCommon.startIterationsA
68 && aux.i < fractal->transformCommon.stopIterationsA)
69 {
70 if (fabs(z.x) > fractal->mandelbox.foldingLimit)
71 {
72 z.x = sign(z.x) * fractal->mandelbox.foldingValue - z.x;
73 colorAdd += fractal->mandelbox.color.factor.x;
74 }
75 if (fabs(z.y) > fractal->mandelbox.foldingLimit)
76 {
77 z.y = sign(z.y) * fractal->mandelbox.foldingValue - z.y;
78 colorAdd += fractal->mandelbox.color.factor.y;
79 }
80 double zLimit = fractal->mandelbox.foldingLimit * fractal->transformCommon.scale1;
81 double zValue = fractal->mandelbox.foldingValue * fractal->transformCommon.scale1;
82 if (fabs(z.z) > zLimit)
83 {
84 z.z = sign(z.z) * zValue - z.z;
85 colorAdd += fractal->mandelbox.color.factor.z;
86 }
87 }
88 }
89
90 if (aux.i >= fractal->transformCommon.startIterationsB
91 && aux.i < fractal->transformCommon.stopIterationsB)
92 {
93 double r2 = z.Dot(z);
94 z += fractal->mandelbox.offset;
95 if (r2 < fractal->mandelbox.mR2)
96 {
97 z *= fractal->mandelbox.mboxFactor1;
98 aux.DE *= fractal->mandelbox.mboxFactor1;
99 colorAdd += fractal->mandelbox.color.factorSp1;
100 }
101 else if (r2 < fractal->mandelbox.fR2)
102 {
103 double tglad_factor2 = fractal->mandelbox.fR2 / r2;
104 z *= tglad_factor2;
105 aux.DE *= tglad_factor2;
106 colorAdd += fractal->mandelbox.color.factorSp2;
107 }
108 z -= fractal->mandelbox.offset;
109 }
110 if (fractal->mandelbox.mainRotationEnabled && aux.i >= fractal->transformCommon.startIterationsR
111 && aux.i < fractal->transformCommon.stopIterationsR)
112 z = fractal->mandelbox.mainRot.RotateVector(z);
113
114 if (aux.i >= fractal->transformCommon.startIterationsS
115 && aux.i < fractal->transformCommon.stopIterationsS)
116 {
117 z = z * fractal->mandelbox.scale;
118 aux.DE = aux.DE * fabs(fractal->mandelbox.scale) + 1.0;
119 }
120
121 if (fractal->transformCommon.addCpixelEnabledFalse)
122 {
123 CVector4 tempC = c;
124 if (fractal->transformCommon.alternateEnabledFalse) // alternate
125 {
126 tempC = aux.c;
127 switch (fractal->mandelbulbMulti.orderOfXYZ)
128 {
129 case multi_OrderOfXYZ_xyz:
130 default: tempC = CVector4(tempC.x, tempC.y, tempC.z, tempC.w); break;
131 case multi_OrderOfXYZ_xzy: tempC = CVector4(tempC.x, tempC.z, tempC.y, tempC.w); break;
132 case multi_OrderOfXYZ_yxz: tempC = CVector4(tempC.y, tempC.x, tempC.z, tempC.w); break;
133 case multi_OrderOfXYZ_yzx: tempC = CVector4(tempC.y, tempC.z, tempC.x, tempC.w); break;
134 case multi_OrderOfXYZ_zxy: tempC = CVector4(tempC.z, tempC.x, tempC.y, tempC.w); break;
135 case multi_OrderOfXYZ_zyx: tempC = CVector4(tempC.z, tempC.y, tempC.x, tempC.w); break;
136 }
137 aux.c = tempC;
138 }
139 else
140 {
141 switch (fractal->mandelbulbMulti.orderOfXYZ)
142 {
143 case multi_OrderOfXYZ_xyz:
144 default: tempC = CVector4(c.x, c.y, c.z, c.w); break;
145 case multi_OrderOfXYZ_xzy: tempC = CVector4(c.x, c.z, c.y, c.w); break;
146 case multi_OrderOfXYZ_yxz: tempC = CVector4(c.y, c.x, c.z, c.w); break;
147 case multi_OrderOfXYZ_yzx: tempC = CVector4(c.y, c.z, c.x, c.w); break;
148 case multi_OrderOfXYZ_zxy: tempC = CVector4(c.z, c.x, c.y, c.w); break;
149 case multi_OrderOfXYZ_zyx: tempC = CVector4(c.z, c.y, c.x, c.w); break;
150 }
151 }
152 z += tempC * fractal->transformCommon.constantMultiplier111;
153 }
154 if (fractal->transformCommon.functionEnabled && aux.i >= fractal->transformCommon.startIterationsM
155 && aux.i < fractal->transformCommon.stopIterationsM)
156 {
157 int count = fractal->transformCommon.int1; // Menger Sponge
158 int k;
159 for (k = 0; k < count; k++)
160 {
161 z = fabs(z);
162 if (z.x - z.y < 0.0) swap(z.y, z.x);
163 if (z.x - z.z < 0.0) swap(z.z, z.x);
164 if (z.y - z.z < 0.0) swap(z.z, z.y);
165 z *= fractal->transformCommon.scale3;
166 z.x -= 2.0 * fractal->transformCommon.constantMultiplierA111.x;
167 z.y -= 2.0 * fractal->transformCommon.constantMultiplierA111.y;
168 if (z.z > 1.0) z.z -= 2.0 * fractal->transformCommon.constantMultiplierA111.z;
169 aux.DE *= fabs(fractal->transformCommon.scale3 * fractal->transformCommon.scaleA1);
170
171 z += fractal->transformCommon.additionConstantA000;
172
173 if (fractal->transformCommon.functionEnabledxFalse) // addCpixel options
174 {
175 switch (fractal->mandelbulbMulti.orderOfXYZC)
176 {
177 case multi_OrderOfXYZ_xyz:
178 default: c = CVector4(c.x, c.y, c.z, c.w); break;
179 case multi_OrderOfXYZ_xzy: c = CVector4(c.x, c.z, c.y, c.w); break;
180 case multi_OrderOfXYZ_yxz: c = CVector4(c.y, c.x, c.z, c.w); break;
181 case multi_OrderOfXYZ_yzx: c = CVector4(c.y, c.z, c.x, c.w); break;
182 case multi_OrderOfXYZ_zxy: c = CVector4(c.z, c.x, c.y, c.w); break;
183 case multi_OrderOfXYZ_zyx: c = CVector4(c.z, c.y, c.x, c.w); break;
184 }
185 z += c * fractal->transformCommon.constantMultiplierB111;
186 }
187 }
188 }
189 if (fractal->analyticDE.enabledFalse)
190 aux.DE = aux.DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
191
192 aux.color += colorAdd;
193 }
194