/******************************************************************** Minecraft: Pocket Edition - Decompilation Project Copyright (C) 2023 iProgramInCpp The following code is licensed under the BSD 1 clause license. SPDX-License-Identifier: BSD-1-Clause ********************************************************************/ #include "ImprovedNoise.hpp" #include "common/Mth.hpp" ImprovedNoise::ImprovedNoise() { Random random(1); init(&random); } ImprovedNoise::ImprovedNoise(Random* pRandom) { init(pRandom); } void ImprovedNoise::init(Random* pRandom) { m_offsetX = pRandom->nextFloat() * 256.0f; m_offsetY = pRandom->nextFloat() * 256.0f; m_offsetZ = pRandom->nextFloat() * 256.0f; for (int i = 0; i < 256; i++) m_permutation[i] = i; for (int i = 0; i < 256; i++) { int x = pRandom->nextInt(256 - i) + i; int t = m_permutation[i]; m_permutation[i] = m_permutation[x]; m_permutation[x] = t; m_permutation[256 + i] = m_permutation[i]; } } float ImprovedNoise::getValue(float x, float y) { return getValue(x, y, 0.0f); } float ImprovedNoise::getValue(float x, float y, float z) { return noise(x, y, z); } float ImprovedNoise::lerp(float prog, float a, float b) { return a + (b - a) * prog; } float ImprovedNoise::grad(int hash, float x, float y, float z) { int h = hash & 0xF; float u = h < 8 ? x : y; float v = h < 4 ? y : h == 12 || h == 14 ? x : z; return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); } float ImprovedNoise::grad2(int hash, float x, float z) { return grad(hash, x, 0.0f, z); } float ImprovedNoise::fade(float x) { return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f); } float ImprovedNoise::noise(float x, float y, float z) { // couldn't figure out how to get it to work well enough so I just decided to port the original implementation from: // https://cs.nyu.edu/~perlin/noise/ x += m_offsetX; y += m_offsetY; z += m_offsetZ; int X = Mth::floor(x) & 255, Y = Mth::floor(y) & 255, Z = Mth::floor(z) & 255; x -= Mth::floor(x); y -= Mth::floor(y); z -= Mth::floor(z); float u = fade(x), v = fade(y), w = fade(z); int* p = m_permutation; int A = p[X ] + Y, AA = p[A] + Z, AB = p[A + 1] + Z, B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), grad(p[BA ], x-1, y , z )), lerp(u, grad(p[AB ], x , y-1, z ), grad(p[BB ], x-1, y-1, z ))), lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), grad(p[BA+1], x-1, y , z-1 )), lerp(u, grad(p[AB+1], x , y-1, z-1 ), grad(p[BB+1], x-1, y-1, z-1 )))); } void ImprovedNoise::add(float* a2, float a3, float a4, float a5, int a6, int a7, int a8, float a9, float a10, float a11, float a12) { // @TODO: clean this up if (a7 == 1) { for (int i = 0; i < a6; i++) { float x2 = m_offsetX + a9 * (i + a3); int x3 = Mth::floor(x2); float x4 = float(x3); float x5 = x2 - x4; int* x6 = &m_permutation[uint8_t(x3)]; int* x8 = &m_permutation[uint8_t(x3 + 1)]; float* x7 = &a2[a8 * i]; for (int j = 0; j < a8; j++) { float x9 = m_offsetZ + a11 * (j + a5); int x10 = Mth::floor(x9); float x11 = float(x10); float x12 = x9 - x11; int* x13 = &m_permutation[uint8_t(x10) + m_permutation[*x6]]; int* x15 = &m_permutation[uint8_t(x10) + m_permutation[*x8]]; float x16 = grad2(*x13, x5, x12); float x17 = grad(*x15, x5 - 1, 0, x12); float x18 = lerp(fade(x5), x16, x17); float x19 = grad(x13[1], x5, 0, x12 - 1); float x20 = grad(x15[1], x5 - 1, 0, x12 - 1); float x21 = lerp(fade(x5), x19, x20); *x7 += (1.0f / a12) * lerp(fade(x12), x18, x21); x7++; } } return; } float x30 = 0, x31 = 0, x32 = 0, x33 = 0; int x34 = -1, x35 = 0; for (int i = 0; i < a6; i++) { float x36 = m_offsetX + a9 * (i + a3); int x37 = Mth::floor(x36); float x38 = float(x37); float x39 = x36 - x38; float x40 = fade(x39); if (a8 <= 0) continue; int* x42 = &m_permutation[uint8_t(x37)]; int* x43 = &m_permutation[uint8_t(x37) + 1]; for (int j = 0; j < a8; j++) { float x44 = m_offsetZ + a11 * (j + a5); int x45 = Mth::floor(x44); float x46 = float(x45); float x47 = x44 - x46; uint8_t x48 = uint8_t(x45); if (a7 <= 0) continue; float* x49 = &a2[x35]; for (int k = 0; k < a7; k++) { float x50 = m_offsetY + a10 * (k + a4); int x51 = Mth::floor(x50); float x52 = float(x51); float x53 = x50 - x52; uint8_t bx51 = uint8_t(x51); if (k == 0 || bx51 != x34) { int* x54 = &m_permutation[bx51 + *x42]; int x55 = x54[0] + x48; int x56 = x54[1] + x48; int* x57 = &m_permutation[bx51 + *x43]; int x58 = x57[1] + x48; int* x59 = &m_permutation[*x57 + x48]; float x60 = grad(m_permutation[x55], x39, x53, x47); float x61 = grad(*x59, x39 - 1, x53, x47); x33 = lerp(x40, x60, x61); float x62 = grad(m_permutation[x56], x39, x53 - 1, x47); float x63 = grad(m_permutation[x58], x39 - 1, x53 - 1, x47); x32 = lerp(x40, x62, x63); float x64 = grad(m_permutation[x55 + 1], x39, x53, x47 - 1); float x65 = grad(x59[1], x39 - 1, x53, x47 - 1); x31 = lerp(x40, x64, x65); float x66 = grad(m_permutation[x56 + 1], x39, x53 - 1, x47 - 1); float x67 = grad(m_permutation[x58 + 1], x39 - 1, x53 - 1, x47 - 1); x34 = bx51; x30 = lerp(x40, x66, x67); } float x68 = lerp(fade(x53), x33, x32); float x69 = lerp(fade(x53), x31, x30); *x49 += (1.0f / a12) * lerp(fade(x47), x68, x69); x49++; } x35 += a7; } } }