diff options
author | paramat <mat.gregory@virginmedia.com> | 2015-12-08 05:40:36 +0000 |
---|---|---|
committer | paramat <mat.gregory@virginmedia.com> | 2015-12-15 04:18:19 +0000 |
commit | c26eb87aec7438d167fa2f460a3f412db09c0ac5 (patch) | |
tree | 0dfafc32c1f82da3b136283f09bc37239b75c56f /src/mapgen_fractal.cpp | |
parent | aed10765f208aedf324128972c74ecc033bb5035 (diff) | |
download | minetest-c26eb87aec7438d167fa2f460a3f412db09c0ac5.tar.gz minetest-c26eb87aec7438d167fa2f460a3f412db09c0ac5.tar.bz2 minetest-c26eb87aec7438d167fa2f460a3f412db09c0ac5.zip |
Mgfractal: Add 3D and 4D fractals
3D Mandelbrot/Mandelbar
3D Christmas Tree
3D Mandelbulb
3D Cosine Mandelbulb
4D Mandelbulb
Plus corresponding julia set for each
Add credits for formulas
Rename parameter 'formula' to 'fractal'
Speed optimisations
Diffstat (limited to 'src/mapgen_fractal.cpp')
-rw-r--r-- | src/mapgen_fractal.cpp | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 14dfe5c85..6c03c4ca9 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -66,7 +66,7 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams; this->spflags = sp->spflags; - this->formula = sp->formula; + this->fractal = sp->fractal; this->iterations = sp->iterations; this->scale = sp->scale; this->offset = sp->offset; @@ -77,6 +77,9 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * this->julia_z = sp->julia_z; this->julia_w = sp->julia_w; + this->formula = fractal / 2 + fractal % 2; + this->julia = fractal % 2 == 0; + //// 2D terrain noise noise_seabed = new Noise(&sp->np_seabed, seed, csize.X, csize.Z); noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); @@ -141,7 +144,7 @@ MapgenFractalParams::MapgenFractalParams() { spflags = 0; - formula = 1; + fractal = 1; iterations = 11; scale = v3f(4096.0, 1024.0, 4096.0); offset = v3f(1.79, 0.0, 0.0); @@ -163,7 +166,7 @@ void MapgenFractalParams::readParams(const Settings *settings) { settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); - settings->getU16NoEx("mgfractal_formula", formula); + settings->getU16NoEx("mgfractal_fractal", fractal); settings->getU16NoEx("mgfractal_iterations", iterations); settings->getV3FNoEx("mgfractal_scale", scale); settings->getV3FNoEx("mgfractal_offset", offset); @@ -185,7 +188,7 @@ void MapgenFractalParams::writeParams(Settings *settings) const { settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX); - settings->setU16("mgfractal_formula", formula); + settings->setU16("mgfractal_fractal", fractal); settings->setU16("mgfractal_iterations", iterations); settings->setV3F("mgfractal_scale", scale); settings->setV3F("mgfractal_offset", offset); @@ -368,7 +371,7 @@ bool MapgenFractal::getFractalAtPoint(s16 x, s16 y, s16 z) { float cx, cy, cz, cw, ox, oy, oz, ow; - if (formula % 2 == 0) { // Julia sets, formula = 2, 4, 6, 8 + if (julia) { // Julia set cx = julia_x; cy = julia_y; cz = julia_z; @@ -377,7 +380,7 @@ bool MapgenFractal::getFractalAtPoint(s16 x, s16 y, s16 z) oy = (float)y / scale.Y - offset.Y; oz = (float)z / scale.Z - offset.Z; ow = slice_w; - } else { // Mandelbrot sets, formula = 1, 3, 5, 7 + } else { // Mandelbrot set cx = (float)x / scale.X - offset.X; cy = (float)y / scale.Y - offset.Y; cz = (float)z / scale.Z - offset.Z; @@ -388,32 +391,87 @@ bool MapgenFractal::getFractalAtPoint(s16 x, s16 y, s16 z) ow = 0.0f; } + float nx = 0.0f; + float ny = 0.0f; + float nz = 0.0f; + float nw = 0.0f; + for (u16 iter = 0; iter < iterations; iter++) { - float nx = 0.0f; - float ny = 0.0f; - float nz = 0.0f; - float nw = 0.0f; - if (formula == 1 || formula == 2) { // 4D "Roundy" Mandelbrot/Julia Set + if (formula == 1) { // 4D "Roundy" nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; ny = 2.0f * (ox * oy + oz * ow) + cy; nz = 2.0f * (ox * oz + oy * ow) + cz; nw = 2.0f * (ox * ow + oy * oz) + cw; - } else if (formula == 3 || formula == 4) { // 4D "Squarry" Mandelbrot/Julia Set + } else if (formula == 2) { // 4D "Squarry" nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; ny = 2.0f * (ox * oy + oz * ow) + cy; nz = 2.0f * (ox * oz + oy * ow) + cz; nw = 2.0f * (ox * ow - oy * oz) + cw; - } else if (formula == 5 || formula == 6) { // 4D "Mandy Cousin" Mandelbrot/Julia Set + } else if (formula == 3) { // 4D "Mandy Cousin" nx = ox * ox - oy * oy - oz * oz + ow * ow + cx; ny = 2.0f * (ox * oy + oz * ow) + cy; nz = 2.0f * (ox * oz + oy * ow) + cz; nw = 2.0f * (ox * ow + oy * oz) + cw; - } else if (formula == 7 || formula == 8) { // 4D "Variation" Mandelbrot/Julia Set + } else if (formula == 4) { // 4D "Variation" nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; ny = 2.0f * (ox * oy + oz * ow) + cy; nz = 2.0f * (ox * oz - oy * ow) + cz; nw = 2.0f * (ox * ow + oy * oz) + cw; + } else if (formula == 5) { // 3D "Mandelbrot/Mandelbar" + nx = ox * ox - oy * oy - oz * oz + cx; + ny = 2.0f * ox * oy + cy; + nz = -2.0f * ox * oz + cz; + } else if (formula == 6) { // 3D "Christmas Tree" + // Altering the formula here is necessary to avoid division by zero + if (fabs(oz) < 0.000000001f) { + nx = ox * ox - oy * oy - oz * oz + cx; + ny = 2.0f * oy * ox + cy; + nz = 4.0f * oz * ox + cz; + } else { + float a = (2.0f * ox) / (sqrt(oy * oy + oz * oz)); + nx = ox * ox - oy * oy - oz * oz + cx; + ny = a * (oy * oy - oz * oz) + cy; + nz = a * 2.0f * oy * oz + cz; + } + } else if (formula == 7) { // 3D "Mandelbulb" + if (fabs(oy) < 0.000000001f) { + nx = ox * ox - oz * oz + cx; + ny = cy; + nz = -2.0f * oz * sqrt(ox * ox) + cz; + } else { + float a = 1.0f - (oz * oz) / (ox * ox + oy * oy); + nx = (ox * ox - oy * oy) * a + cx; + ny = 2.0f * ox * oy * a + cy; + nz = -2.0f * oz * sqrt(ox * ox + oy * oy) + cz; + } + } else if (formula == 8) { // 3D "Cosine Mandelbulb" + if (fabs(oy) < 0.000000001f) { + nx = 2.0f * ox * oz + cx; + ny = 4.0f * oy * oz + cy; + nz = oz * oz - ox * ox - oy * oy + cz; + } else { + float a = (2.0f * oz) / sqrt(ox * ox + oy * oy); + nx = (ox * ox - oy * oy) * a + cx; + ny = 2.0f * ox * oy * a + cy; + nz = oz * oz - ox * ox - oy * oy + cz; + } + } else if (formula == 9) { // 4D "Mandelbulb" + float rxy = sqrt(ox * ox + oy * oy); + float rxyz = sqrt(ox * ox + oy * oy + oz * oz); + if (fabs(ow) < 0.000000001f && fabs(oz) < 0.000000001f) { + nx = (ox * ox - oy * oy) + cx; + ny = 2.0f * ox * oy + cy; + nz = -2.0f * rxy * oz + cz; + nw = 2.0f * rxyz * ow + cw; + } else { + float a = 1.0f - (ow * ow) / (rxyz * rxyz); + float b = a * (1.0f - (oz * oz) / (rxy * rxy)); + nx = (ox * ox - oy * oy) * b + cx; + ny = 2.0f * ox * oy * b + cy; + nz = -2.0f * rxy * oz * a + cz; + nw = 2.0f * rxyz * ow + cw; + } } if (nx * nx + ny * ny + nz * nz + nw * nw > 4.0f) |