X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnoise.cpp;h=35057146da9c919c7bb8d90f64451bc51dd0431c;hb=2fee2baf98cd452f7d0e4acb6c82617b7c7b995a;hp=a98dd5886a579f8fdf6796287647bd70de8f6562;hpb=15f27a19378345c22b07e37ab324581d55ad9c5b;p=oweals%2Fminetest.git diff --git a/src/noise.cpp b/src/noise.cpp index a98dd5886..35057146d 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -1,18 +1,19 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -20,81 +21,599 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "noise.h" #include +#include // memset +#include "debug.h" +#include "util/numeric.h" -#define NOISE_MAGIC_X 1619 -#define NOISE_MAGIC_Y 31337 +#define NOISE_MAGIC_X 1619 +#define NOISE_MAGIC_Y 31337 +#define NOISE_MAGIC_Z 52591 #define NOISE_MAGIC_SEED 1013 -double cos_lookup[16] = { - 1.0,0.9238,0.7071,0.3826,0,-0.3826,-0.7071,-0.9238, - 1.0,-0.9238,-0.7071,-0.3826,0,0.3826,0.7071,0.9238 +float cos_lookup[16] = { + 1.0, 0.9238, 0.7071, 0.3826, 0, -0.3826, -0.7071, -0.9238, + 1.0, -0.9238, -0.7071, -0.3826, 0, 0.3826, 0.7071, 0.9238 }; -double dotProduct(double vx, double vy, double wx, double wy){ - return vx*wx+vy*wy; + +/////////////////////////////////////////////////////////////////////////////// + + +//noise poly: p(n) = 60493n^3 + 19990303n + 137612589 +float noise2d(int x, int y, int seed) { + int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + + NOISE_MAGIC_SEED * seed) & 0x7fffffff; + n = (n >> 13) ^ n; + n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 1.f - (float)n / 0x40000000; +} + + +float noise3d(int x, int y, int z, int seed) { + int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + NOISE_MAGIC_Z * z + + NOISE_MAGIC_SEED * seed) & 0x7fffffff; + n = (n >> 13) ^ n; + n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 1.f - (float)n / 0x40000000; +} + + +float dotProduct(float vx, float vy, float wx, float wy) { + return vx * wx + vy * wy; +} + + +inline float linearInterpolation(float v0, float v1, float t) { + return v0 + (v1 - v0) * t; } - -double easeCurve(double t){ - return 6*pow(t,5)-15*pow(t,4)+10*pow(t,3); + + +float biLinearInterpolation(float v00, float v10, + float v01, float v11, + float x, float y) { + float tx = easeCurve(x); + float ty = easeCurve(y); + float u = linearInterpolation(v00, v10, tx); + float v = linearInterpolation(v01, v11, tx); + return linearInterpolation(u, v, ty); } - -double linearInterpolation(double x0, double x1, double t){ - return x0+(x1-x0)*t; + + +float biLinearInterpolationNoEase(float x0y0, float x1y0, + float x0y1, float x1y1, + float x, float y) { + float u = linearInterpolation(x0y0, x1y0, x); + float v = linearInterpolation(x0y1, x1y1, x); + return linearInterpolation(u, v, y); } - -double biLinearInterpolation(double x0y0, double x1y0, double x0y1, double x1y1, double x, double y){ - double tx = easeCurve(x); - double ty = easeCurve(y); - double u = linearInterpolation(x0y0,x1y0,tx); - double v = linearInterpolation(x0y1,x1y1,tx); - return linearInterpolation(u,v,ty); + + +float triLinearInterpolation( + float v000, float v100, float v010, float v110, + float v001, float v101, float v011, float v111, + float x, float y, float z) { + float u = biLinearInterpolationNoEase(v000, v100, v010, v110, x, y); + float v = biLinearInterpolationNoEase(v001, v101, v011, v111, x, y); + return linearInterpolation(u, v, z); } -double noise2d(int x, int y, int seed) + +#if 0 +float triLinearInterpolation( + float v000, float v100, float v010, float v110, + float v001, float v101, float v011, float v111, + float x, float y, float z) { - int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y - + NOISE_MAGIC_SEED * seed) & 0x7fffffff; - n = (n>>13)^n; - n = (n * (n*n*60493+19990303) + 1376312589) & 0x7fffffff; - return 1.0 - (double)n/1073741824; + /*float tx = easeCurve(x); + float ty = easeCurve(y); + float tz = easeCurve(z);*/ + float tx = x; + float ty = y; + float tz = z; + return( + v000 * (1 - tx) * (1 - ty) * (1 - tz) + + v100 * tx * (1 - ty) * (1 - tz) + + v010 * (1 - tx) * ty * (1 - tz) + + v110 * tx * ty * (1 - tz) + + v001 * (1 - tx) * (1 - ty) * tz + + v101 * tx * (1 - ty) * tz + + v011 * (1 - tx) * ty * tz + + v111 * tx * ty * tz + ); } +#endif + -double noise2d_gradient(double x, double y, int seed) +#if 0 +float noise2d_gradient(float x, float y, int seed) { + // Calculate the integer coordinates int x0 = (x > 0.0 ? (int)x : (int)x - 1); int y0 = (y > 0.0 ? (int)y : (int)y - 1); - double xl = x - (double)x0; - double yl = y - (double)y0; + // Calculate the remaining part of the coordinates + float xl = x - (float)x0; + float yl = y - (float)y0; + // Calculate random cosine lookup table indices for the integer corners. + // They are looked up as unit vector gradients from the lookup table. int n00 = (int)((noise2d(x0, y0, seed)+1)*8); int n10 = (int)((noise2d(x0+1, y0, seed)+1)*8); int n01 = (int)((noise2d(x0, y0+1, seed)+1)*8); int n11 = (int)((noise2d(x0+1, y0+1, seed)+1)*8); - /* In this format, these fail to work on MSVC8 if n00 < 4 - double s = dotProduct(cos_lookup[n00], cos_lookup[(n00-4)%16], xl, yl); - double u = dotProduct(-cos_lookup[n10], cos_lookup[(n10-4)%16], 1.-xl, yl); - double v = dotProduct(cos_lookup[n01], -cos_lookup[(n01-4)%16], xl, 1.-yl); - double w = dotProduct(-cos_lookup[n11], -cos_lookup[(n11-4)%16], 1.-xl, 1.-yl);*/ - double s = dotProduct(cos_lookup[n00], cos_lookup[(n00+12)%16], xl, yl); - double u = dotProduct(-cos_lookup[n10], cos_lookup[(n10+12)%16], 1.-xl, yl); - double v = dotProduct(cos_lookup[n01], -cos_lookup[(n01+12)%16], xl, 1.-yl); - double w = dotProduct(-cos_lookup[n11], -cos_lookup[(n11+12)%16], 1.-xl, 1.-yl); - /*std::cout<<"x="<