aboutsummaryrefslogtreecommitdiff
path: root/src/httpfetch.cpp
Commit message (Collapse)AuthorAge
* Rework Settings to support arbitrary hierarchies (#11352)sfan52021-06-23
|
* Sort out cURL timeouts and increase defaultsfan52021-04-02
|
* Add PUT and DELETE request + specific method value to HTTP API (#9909)Lejo2020-07-29
|
* httpfetch: Disable IPv6 here too if requested by settings (#8399)sfan52019-03-18
|
* Add online content repositoryrubenwardy2018-04-19
| | | | Replaces mods and texture pack tabs with a single content tab
* httpfetch: Enable gzip supportsfan52017-11-04
|
* Remove DSTACK support (#6346)Loïc Blot2017-08-30
| | | Debugstacks is not useful, we don't really use it, the DebugStack is not pertinent, gdb and lldb are better if we really want to debug.
* Network cleanup (#6302)Loïc Blot2017-08-24
| | | | | | | | | | | | | | | | | | | | | | | * Cleanup network headers * Move peerhandler to a specific header to reduce compilation times * Move socket.cpp/h to network folder * More work * Network code cleanups * Move socket.{cpp,h} to network folder * Move Address object to network/address.{cpp,h} * Move network exceptions to network/networkexceptions.h * Client: use unique_ptr for Connection * Server/ClientIface: use shared_ptr for Connection * Format fixes * Remove socket.cpp socket.h from clang-format whitelist * Also fix NetworkPacket code style & make it under clang-format
* Modernize code: very last fixes (#6290)Loïc Blot2017-08-20
| | | Last modernization fixes
* Cpp11 initializers 2 (#5999)Loïc Blot2017-06-17
| | | | | | | | | | * C++11 patchset 10: continue cleanup on constructors * Drop obsolete bool MainMenuData::enable_public (setting is called with cURL in server loop) * More classes cleanup * More classes cleanup + change NULL tests to boolean tests
* Use C++11 mutexes only (remove compat code) (#5922)Loïc Blot2017-06-06
| | | | * Fix event LINT & remove default constructor/destructors * remove compat code & modernize autolock header
* Fix various copy instead of const ref reported by cppcheck (part 3) (#5616)Loïc Blot2017-04-20
| | | | * Also remove 2 non declared but defined functions * Make some functions around const ref changes const
* Fix various copy instead of const ref reported by cppcheck (#5615)Loïc Blot2017-04-19
| | | | * Also remove InventoryList::peekItem unused function * Fix some post increment to preincrement reported by cppcheck
* Add Lua interface to HTTPFetchRequestJeija2016-02-22
| | | | | | | | | | This allows mods to perform both asynchronous and synchronous HTTP requests. Mods are only granted access to HTTP APIs if either mod security is disabled or if they are whitelisted in any of the the secure.http_mods and secure.trusted_mods settings. Adds httpfetch_caller_alloc_secure to generate random, non-predictable caller IDs so that lua mods cannot spy on each others HTTP queries.
* Fix HTTPFetchRequest performing a GET request if post_data is suppliedJeija2016-02-22
| | | | Instead, perform a POST request with post_data.
* Rename macros with two leading underscoresShadowNinja2015-10-14
| | | | These names are reserved for the compiler/library implementations.
* Always use errorstream for DEBUG_EXCEPTION_HANDLERShadowNinja2015-10-14
|
* Clean up threadingShadowNinja2015-08-23
| | | | | | | | | | | | | | | | | | | | * Rename everything. * Strip J prefix. * Change UpperCamelCase functions to lowerCamelCase. * Remove global (!) semaphore count mutex on OSX. * Remove semaphore count getter (unused, unsafe, depended on internal API functions on Windows, and used a hack on OSX). * Add `Atomic<type>`. * Make `Thread` handle thread names. * Add support for C++11 multi-threading. * Combine pthread and win32 sources. * Remove `ThreadStarted` (unused, unneeded). * Move some includes from the headers to the sources. * Move all of `Event` into its header (allows inlining with no new includes). * Make `Event` use `Semaphore` (except on Windows). * Move some porting functions into `Thread`. * Integrate logging with `Thread`. * Add threading test.
* Replace instances of std::map<std::string, std::string> with StringMapkwolekr2015-05-19
| | | | | | Also, clean up surrounding code style Replace by-value parameter passing with const refs when possible Fix post-increment of iterators
* Revert the upper-case PROJECT_NAME nonsense that was part of #2402sfan52015-04-27
|
* Move globals from main.cpp to more sane locationsCraig Robbins2015-04-01
| | | | | | | | | | | | Move debug streams to log.cpp|h Move GUI-related globals to clientlauncher Move g_settings and g_settings_path to settings.cpp|h Move g_menuclouds to clouds.cpp|h Move g_profiler to profiler.cpp|h
* Clean up and tweak build systemShadowNinja2015-03-27
| | | | | | | | | | | | | | | | * Combine client and server man pages. * Update unit test options and available databases in man page. * Add `--worldname` to man page. * Fix a bunch of places where `"Minetest"` was used directly instead of `PROJECT_NAME`. * Disable server build by default on all operating systems. * Make `ENABLE_FREETYPE` not fail if FreeType isn't found. * Enable LevelDB, Redis, and FreeType detection by default. * Remove the `VERSION_PATCH_ORIG` hack. * Add option to search for and use system JSONCPP. * Remove broken LuaJIT version detection. * Rename `DISABLE_LUAJIT` to `ENABLE_LUAJIT`. * Rename `minetest_*` variables in `version.{h,cpp}` to `g_*`. * Clean up style of CMake files.
* For usages of assert() that are meant to persist in Release builds (when ↵Craig Robbins2015-03-07
| | | | NDEBUG is defined), replace those usages with persistent alternatives
* Use std::queue for HTTPFetchRequest and std::vector for log_output instead ↵Loic Blot2015-03-05
| | | | of std::list
* Remove unused variables to make clang happyLoic Blot2015-02-12
|
* Use configured bind_address for HTTPFetchShadowNinja2014-09-18
|
* Reduce indentation of HTTPFetchOngoingShadowNinja2014-09-18
| | | | Also clean up some related things.
* Add support for multipart/form-data to HTTPFetch for server announcingShadowNinja2014-06-30
|
* Add support for Android 2.3+sapier2014-06-29
| | | | | | | | | | | | | There have been plenty of ppl involved in creating this version. I don't wanna mention names as I'm sure I'd forget someone so I just tell where help has been done: - The partial android versions done by various ppl - Testing on different android devices - reviewing code (especially the in core changes) - testing controls - reviewing texts A big thank you to everyone helping this to be completed!
* Remove dependency on marshal and many other async changesShadowNinja2014-04-27
| | | | | | | | | | | | This makes a number of changes: * Remove the dependency on marshal by using string.dump and loadstring. * Use lua_tolstring rather than having Lua functions pass string lengths to C++. * Move lua_api/l_async_events.* to cpp_api/s_async.*, where it belongs. * Make AsyncWorkerThread a child of ScriptApiBase, this removes some duplicate functionality. * Don't wait for async threads to shut down. (Is this safe? Might result in corruption if the thread is writing to a file.) * Pop more unused items from the stack * Code style fixes * Other misc changes
* Add support for named threads (atm linux only)sapier2014-04-09
|
* Include system info in the HTTP user agent on WindowsSfan52014-01-23
|
* Deindent HTTPFetchRequest::HTTPFetchRequest()ShadowNinja2014-01-16
|
* Make default User-agent follow RFC 2616ShadowNinja2014-01-15
|
* Fix building with MinGWSfan52014-01-15
|
* Fix check for max_fd == -1 should actually be max_fd != -1sapier2014-01-10
|
* Make MutexQueue use jsemaphore for signalingsapier2014-01-10
|
* Send long announce as POST, show OS in useragentproller2014-01-07
| | | | | Add lag reporting to masterserver (average dtime) StyledWriter -> FastWriter in masterserver announce
* Use sleep_ms instead of select in httpfetch when max_fd == -1, fixes WSAEINVALKahrl2013-12-24
|
* Fix broken httpfetch due to SimpleThread removalsapier2013-12-16
|
* Fix MSVC compiling issueBlockMen2013-12-16
|
* Replace SimpleThread by JThread now implementing same featuressapier2013-12-15
|
* Replace any direct curl usage by httpfetchsapier2013-12-13
|
* Use httpfetch_async in serverlist announce codeKahrl2013-12-13
|
* Implement httpfetch module and initialize it from main()Kahrl2013-12-13
Add curl_parallel_limit setting that will replace media_fetch_threads in a later commit. Fix a typo in MutexedQueue::pop_back() that made it impossible to compile code that used this function. (Noticed this while implementing httpfetch.)
lass="hl opt">, float v111, float x, float y, float z); 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 }; FlagDesc flagdesc_noiseparams[] = { {"defaults", NOISE_FLAG_DEFAULTS}, {"eased", NOISE_FLAG_EASED}, {"absvalue", NOISE_FLAG_ABSVALUE}, {"pointbuffer", NOISE_FLAG_POINTBUFFER}, {"simplex", NOISE_FLAG_SIMPLEX}, {NULL, 0} }; /////////////////////////////////////////////////////////////////////////////// PcgRandom::PcgRandom(u64 state, u64 seq) { seed(state, seq); } void PcgRandom::seed(u64 state, u64 seq) { m_state = 0U; m_inc = (seq << 1u) | 1u; next(); m_state += state; next(); } u32 PcgRandom::next() { u64 oldstate = m_state; m_state = oldstate * 6364136223846793005ULL + m_inc; u32 xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; u32 rot = oldstate >> 59u; return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); } u32 PcgRandom::range(u32 bound) { // If the bound is 0, we cover the whole RNG's range if (bound == 0) return next(); /* If the bound is not a multiple of the RNG's range, it may cause bias, e.g. a RNG has a range from 0 to 3 and we take want a number 0 to 2. Using rand() % 3, the number 0 would be twice as likely to appear. With a very large RNG range, the effect becomes less prevalent but still present. This can be solved by modifying the range of the RNG to become a multiple of bound by dropping values above the a threshold. In our example, threshold == 4 - 3 = 1 % 3 == 1, so reject 0, thus making the range 3 with no bias. This loop looks dangerous, but will always terminate due to the RNG's property of uniformity. */ u32 threshold = -bound % bound; u32 r; while ((r = next()) < threshold) ; return r % bound; } s32 PcgRandom::range(s32 min, s32 max) { if (max < min) throw PrngException("Invalid range (max < min)"); u32 bound = max - min + 1; return range(bound) + min; } void PcgRandom::bytes(void *out, size_t len) { u8 *outb = (u8 *)out; int bytes_left = 0; u32 r; while (len--) { if (bytes_left == 0) { bytes_left = sizeof(u32); r = next(); } *outb = r & 0xFF; outb++; bytes_left--; r >>= CHAR_BIT; } } s32 PcgRandom::randNormalDist(s32 min, s32 max, int num_trials) { s32 accum = 0; for (int i = 0; i != num_trials; i++) accum += range(min, max); return myround((float)accum / num_trials); } /////////////////////////////////////////////////////////////////////////////// float noise2d(int x, int y, int seed) { unsigned 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)(int)n / 0x40000000; } float noise3d(int x, int y, int z, int seed) { unsigned 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)(int)n / 0x40000000; } inline 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; } inline 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); } inline float biLinearInterpolationNoEase( float v00, float v10, float v01, float v11, float x, float y) { float u = linearInterpolation(v00, v10, x); float v = linearInterpolation(v01, v11, x); return linearInterpolation(u, v, y); } 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 tx = easeCurve(x); float ty = easeCurve(y); float tz = easeCurve(z); float u = biLinearInterpolationNoEase(v000, v100, v010, v110, tx, ty); float v = biLinearInterpolationNoEase(v001, v101, v011, v111, tx, ty); return linearInterpolation(u, v, tz); } float triLinearInterpolationNoEase( 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); } float noise2d_gradient(float x, float y, int seed, bool eased) { // Calculate the integer coordinates int x0 = myfloor(x); int y0 = myfloor(y); // Calculate the remaining part of the coordinates float xl = x - (float)x0; float yl = y - (float)y0; // Get values for corners of square float v00 = noise2d(x0, y0, seed); float v10 = noise2d(x0+1, y0, seed); float v01 = noise2d(x0, y0+1, seed); float v11 = noise2d(x0+1, y0+1, seed); // Interpolate if (eased) return biLinearInterpolation(v00, v10, v01, v11, xl, yl); else return biLinearInterpolationNoEase(v00, v10, v01, v11, xl, yl); } float noise3d_gradient(float x, float y, float z, int seed, bool eased) { // Calculate the integer coordinates int x0 = myfloor(x); int y0 = myfloor(y); int z0 = myfloor(z); // Calculate the remaining part of the coordinates float xl = x - (float)x0; float yl = y - (float)y0; float zl = z - (float)z0; // Get values for corners of cube float v000 = noise3d(x0, y0, z0, seed); float v100 = noise3d(x0 + 1, y0, z0, seed); float v010 = noise3d(x0, y0 + 1, z0, seed); float v110 = noise3d(x0 + 1, y0 + 1, z0, seed); float v001 = noise3d(x0, y0, z0 + 1, seed); float v101 = noise3d(x0 + 1, y0, z0 + 1, seed); float v011 = noise3d(x0, y0 + 1, z0 + 1, seed); float v111 = noise3d(x0 + 1, y0 + 1, z0 + 1, seed); // Interpolate if (eased) { return triLinearInterpolation( v000, v100, v010, v110, v001, v101, v011, v111, xl, yl, zl); } else { return triLinearInterpolationNoEase( v000, v100, v010, v110, v001, v101, v011, v111, xl, yl, zl); } } float noise2d_perlin(float x, float y, int seed, int octaves, float persistence, bool eased) { float a = 0; float f = 1.0; float g = 1.0; for (int i = 0; i < octaves; i++) { a += g * noise2d_gradient(x * f, y * f, seed + i, eased); f *= 2.0; g *= persistence; } return a; } float noise2d_perlin_abs(float x, float y, int seed, int octaves, float persistence, bool eased) { float a = 0; float f = 1.0; float g = 1.0; for (int i = 0; i < octaves; i++) { a += g * fabs(noise2d_gradient(x * f, y * f, seed + i, eased)); f *= 2.0; g *= persistence; } return a; } float noise3d_perlin(float x, float y, float z, int seed, int octaves, float persistence, bool eased) { float a = 0; float f = 1.0; float g = 1.0; for (int i = 0; i < octaves; i++) { a += g * noise3d_gradient(x * f, y * f, z * f, seed + i, eased); f *= 2.0; g *= persistence; } return a; } float noise3d_perlin_abs(float x, float y, float z, int seed, int octaves, float persistence, bool eased) { float a = 0; float f = 1.0; float g = 1.0; for (int i = 0; i < octaves; i++) { a += g * fabs(noise3d_gradient(x * f, y * f, z * f, seed + i, eased)); f *= 2.0; g *= persistence; } return a; } float contour(float v) { v = fabs(v); if (v >= 1.0) return 0.0; return (1.0 - v); } ///////////////////////// [ New noise ] //////////////////////////// float NoisePerlin2D(NoiseParams *np, float x, float y, int seed) { float a = 0; float f = 1.0; float g = 1.0; x /= np->spread.X; y /= np->spread.Y; seed += np->seed; for (size_t i = 0; i < np->octaves; i++) { float noiseval = noise2d_gradient(x * f, y * f, seed + i, np->flags & (NOISE_FLAG_DEFAULTS | NOISE_FLAG_EASED)); if (np->flags & NOISE_FLAG_ABSVALUE) noiseval = fabs(noiseval); a += g * noiseval; f *= np->lacunarity; g *= np->persist; } return np->offset + a * np->scale; } float NoisePerlin3D(NoiseParams *np, float x, float y, float z, int seed) { float a = 0; float f = 1.0; float g = 1.0; x /= np->spread.X; y /= np->spread.Y; z /= np->spread.Z; seed += np->seed; for (size_t i = 0; i < np->octaves; i++) { float noiseval = noise3d_gradient(x * f, y * f, z * f, seed + i, np->flags & NOISE_FLAG_EASED); if (np->flags & NOISE_FLAG_ABSVALUE) noiseval = fabs(noiseval); a += g * noiseval; f *= np->lacunarity; g *= np->persist; } return np->offset + a * np->scale; } Noise::Noise(NoiseParams *np_, int seed, u32 sx, u32 sy, u32 sz) { memcpy(&np, np_, sizeof(np)); this->seed = seed; this->sx = sx; this->sy = sy; this->sz = sz; this->persist_buf = NULL; this->gradient_buf = NULL; this->result = NULL; allocBuffers(); } Noise::~Noise() { delete[] gradient_buf; delete[] persist_buf; delete[] noise_buf; delete[] result; } void Noise::allocBuffers() { if (sx < 1) sx = 1; if (sy < 1) sy = 1; if (sz < 1) sz = 1; this->noise_buf = NULL; resizeNoiseBuf(sz > 1); delete[] gradient_buf; delete[] persist_buf; delete[] result; try { size_t bufsize = sx * sy * sz; this->persist_buf = NULL; this->gradient_buf = new float[bufsize]; this->result = new float[bufsize]; } catch (std::bad_alloc &e) { throw InvalidNoiseParamsException(); } } void Noise::setSize(u32 sx, u32 sy, u32 sz) { this->sx = sx; this->sy = sy; this->sz = sz; allocBuffers(); } void Noise::setSpreadFactor(v3f spread) { this->np.spread = spread; resizeNoiseBuf(sz > 1); } void Noise::setOctaves(int octaves) { this->np.octaves = octaves; resizeNoiseBuf(sz > 1); } void Noise::resizeNoiseBuf(bool is3d) { //maximum possible spread value factor float ofactor = (np.lacunarity > 1.0) ? pow(np.lacunarity, np.octaves - 1) : np.lacunarity; // noise lattice point count // (int)(sz * spread * ofactor) is # of lattice points crossed due to length float num_noise_points_x = sx * ofactor / np.spread.X; float num_noise_points_y = sy * ofactor / np.spread.Y; float num_noise_points_z = sz * ofactor / np.spread.Z; // protect against obviously invalid parameters if (num_noise_points_x > 1000000000.f || num_noise_points_y > 1000000000.f || num_noise_points_z > 1000000000.f) throw InvalidNoiseParamsException(); // + 2 for the two initial endpoints // + 1 for potentially crossing a boundary due to offset size_t nlx = (size_t)ceil(num_noise_points_x) + 3; size_t nly = (size_t)ceil(num_noise_points_y) + 3; size_t nlz = is3d ? (size_t)ceil(num_noise_points_z) + 3 : 1; delete[] noise_buf; try { noise_buf = new float[nlx * nly * nlz]; } catch (std::bad_alloc &e) { throw InvalidNoiseParamsException(); } } /* * NB: This algorithm is not optimal in terms of space complexity. The entire * integer lattice of noise points could be done as 2 lines instead, and for 3D, * 2 lines + 2 planes. * However, this would require the noise calls to be interposed with the * interpolation loops, which may trash the icache, leading to lower overall * performance. * Another optimization that could save half as many noise calls is to carry over * values from the previous noise lattice as midpoints in the new lattice for the * next octave. */ #define idx(x, y) ((y) * nlx + (x)) void Noise::gradientMap2D( float x, float y, float step_x, float step_y, int seed) { float v00, v01, v10, v11, u, v, orig_u; u32 index, i, j, noisex, noisey; u32 nlx, nly; s32 x0, y0; bool eased = np.flags & (NOISE_FLAG_DEFAULTS | NOISE_FLAG_EASED); Interp2dFxn interpolate = eased ? biLinearInterpolation : biLinearInterpolationNoEase; x0 = floor(x); y0 = floor(y); u = x - (float)x0; v = y - (float)y0; orig_u = u; //calculate noise point lattice nlx = (u32)(u + sx * step_x) + 2; nly = (u32)(v + sy * step_y) + 2; index = 0; for (j = 0; j != nly; j++) for (i = 0; i != nlx; i++) noise_buf[index++] = noise2d(x0 + i, y0 + j, seed); //calculate interpolations index = 0; noisey = 0; for (j = 0; j != sy; j++) { v00 = noise_buf[idx(0, noisey)]; v10 = noise_buf[idx(1, noisey)]; v01 = noise_buf[idx(0, noisey + 1)]; v11 = noise_buf[idx(1, noisey + 1)]; u = orig_u; noisex = 0; for (i = 0; i != sx; i++) { gradient_buf[index++] = interpolate(v00, v10, v01, v11, u, v); u += step_x; if (u >= 1.0) { u -= 1.0; noisex++; v00 = v10; v01 = v11; v10 = noise_buf[idx(noisex + 1, noisey)]; v11 = noise_buf[idx(noisex + 1, noisey + 1)]; } } v += step_y; if (v >= 1.0) { v -= 1.0; noisey++; } } } #undef idx #define idx(x, y, z) ((z) * nly * nlx + (y) * nlx + (x)) void Noise::gradientMap3D( float x, float y, float z, float step_x, float step_y, float step_z, int seed) { float v000, v010, v100, v110; float v001, v011, v101, v111; float u, v, w, orig_u, orig_v; u32 index, i, j, k, noisex, noisey, noisez; u32 nlx, nly, nlz; s32 x0, y0, z0; Interp3dFxn interpolate = (np.flags & NOISE_FLAG_EASED) ? triLinearInterpolation : triLinearInterpolationNoEase; x0 = floor(x); y0 = floor(y); z0 = floor(z); u = x - (float)x0; v = y - (float)y0; w = z - (float)z0; orig_u = u; orig_v = v; //calculate noise point lattice nlx = (u32)(u + sx * step_x) + 2; nly = (u32)(v + sy * step_y) + 2; nlz = (u32)(w + sz * step_z) + 2; index = 0; for (k = 0; k != nlz; k++) for (j = 0; j != nly; j++) for (i = 0; i != nlx; i++) noise_buf[index++] = noise3d(x0 + i, y0 + j, z0 + k, seed); //calculate interpolations index = 0; noisey = 0; noisez = 0; for (k = 0; k != sz; k++) { v = orig_v; noisey = 0; for (j = 0; j != sy; j++) { v000 = noise_buf[idx(0, noisey, noisez)]; v100 = noise_buf[idx(1, noisey, noisez)]; v010 = noise_buf[idx(0, noisey + 1, noisez)]; v110 = noise_buf[idx(1, noisey + 1, noisez)]; v001 = noise_buf[idx(0, noisey, noisez + 1)]; v101 = noise_buf[idx(1, noisey, noisez + 1)]; v011 = noise_buf[idx(0, noisey + 1, noisez + 1)]; v111 = noise_buf[idx(1, noisey + 1, noisez + 1)]; u = orig_u; noisex = 0; for (i = 0; i != sx; i++) { gradient_buf[index++] = interpolate( v000, v100, v010, v110, v001, v101, v011, v111, u, v, w); u += step_x; if (u >= 1.0) { u -= 1.0; noisex++; v000 = v100; v010 = v110; v100 = noise_buf[idx(noisex + 1, noisey, noisez)]; v110 = noise_buf[idx(noisex + 1, noisey + 1, noisez)]; v001 = v101; v011 = v111; v101 = noise_buf[idx(noisex + 1, noisey, noisez + 1)]; v111 = noise_buf[idx(noisex + 1, noisey + 1, noisez + 1)]; } } v += step_y; if (v >= 1.0) { v -= 1.0; noisey++; } } w += step_z; if (w >= 1.0) { w -= 1.0; noisez++; } } } #undef idx float *Noise::perlinMap2D(float x, float y, float *persistence_map) { float f = 1.0, g = 1.0; size_t bufsize = sx * sy; x /= np.spread.X; y /= np.spread.Y; memset(result, 0, sizeof(float) * bufsize); if (persistence_map) { if (!persist_buf) persist_buf = new float[bufsize]; for (size_t i = 0; i != bufsize; i++) persist_buf[i] = 1.0; } for (size_t oct = 0; oct < np.octaves; oct++) { gradientMap2D(x * f, y * f, f / np.spread.X, f / np.spread.Y, seed + np.seed + oct); updateResults(g, persist_buf, persistence_map, bufsize); f *= np.lacunarity; g *= np.persist; } if (fabs(np.offset - 0.f) > 0.00001 || fabs(np.scale - 1.f) > 0.00001) { for (size_t i = 0; i != bufsize; i++) result[i] = result[i] * np.scale + np.offset; } return result; } float *Noise::perlinMap3D(float x, float y, float z, float *persistence_map) { float f = 1.0, g = 1.0; size_t bufsize = sx * sy * sz; x /= np.spread.X; y /= np.spread.Y; z /= np.spread.Z; memset(result, 0, sizeof(float) * bufsize); if (persistence_map) { if (!persist_buf) persist_buf = new float[bufsize]; for (size_t i = 0; i != bufsize; i++) persist_buf[i] = 1.0; } for (size_t oct = 0; oct < np.octaves; oct++) { gradientMap3D(x * f, y * f, z * f, f / np.spread.X, f / np.spread.Y, f / np.spread.Z, seed + np.seed + oct); updateResults(g, persist_buf, persistence_map, bufsize); f *= np.lacunarity; g *= np.persist; } if (fabs(np.offset - 0.f) > 0.00001 || fabs(np.scale - 1.f) > 0.00001) { for (size_t i = 0; i != bufsize; i++) result[i] = result[i] * np.scale + np.offset; } return result; } void Noise::updateResults(float g, float *gmap, float *persistence_map, size_t bufsize) { // This looks very ugly, but it is 50-70% faster than having // conditional statements inside the loop if (np.flags & NOISE_FLAG_ABSVALUE) { if (persistence_map) { for (size_t i = 0; i != bufsize; i++) { result[i] += gmap[i] * fabs(gradient_buf[i]); gmap[i] *= persistence_map[i]; } } else { for (size_t i = 0; i != bufsize; i++) result[i] += g * fabs(gradient_buf[i]); } } else { if (persistence_map) { for (size_t i = 0; i != bufsize; i++) { result[i] += gmap[i] * gradient_buf[i]; gmap[i] *= persistence_map[i]; } } else { for (size_t i = 0; i != bufsize; i++) result[i] += g * gradient_buf[i]; } } }