MinecraftConsoles/Minecraft.World/PerlinNoise.cpp
2026-03-11 20:04:11 +03:00

99 lines
2.4 KiB
C++

#include "stdafx.h"
#include "PerlinNoise.h"
#include "Random.h"
#include "Mth.h"
PerlinNoise::PerlinNoise(int levels)
{
Random random; // èñïîëüçóåò íîâûé âûñîêîýíòðîïèéíûé seed
init(&random, levels);
}
PerlinNoise::PerlinNoise(Random* random, int levels)
{
init(random, levels);
}
void PerlinNoise::init(Random* random, int levels)
{
MemSect(2);
this->levels = levels;
noiseLevels = new ImprovedNoise * [levels];
for (int i = 0; i < levels; ++i)
{
noiseLevels[i] = new ImprovedNoise(random);
}
MemSect(0);
}
PerlinNoise::~PerlinNoise()
{
for (int i = 0; i < levels; ++i)
delete noiseLevels[i];
delete[] noiseLevels;
}
double PerlinNoise::getValue(double x, double y)
{
double value = 0.0;
double amp = 1.0; // àìïëèòóäà (çäåñü 1/pow â îðèãèíàëå)
for (int i = 0; i < levels; ++i)
{
value += noiseLevels[i]->getValue(x * amp, y * amp) / amp;
amp *= 0.5; // óìåíüøàåì ÷àñòîòó (pow /= 2)
}
return value;
}
double PerlinNoise::getValue(double x, double y, double z)
{
double value = 0.0;
double amp = 1.0;
for (int i = 0; i < levels; ++i)
{
value += noiseLevels[i]->getValue(x * amp, y * amp, z * amp) / amp;
amp *= 0.5;
}
return value;
}
doubleArray PerlinNoise::getRegion(doubleArray buffer,
int x, int y, int z,
int xSize, int ySize, int zSize,
double xScale, double yScale, double zScale)
{
// Èíèöèàëèçàöèÿ áóôåðà íóëÿìè, åñëè íåîáõîäèìî
if (buffer.data == nullptr)
buffer = doubleArray(xSize * ySize * zSize);
else
for (unsigned int i = 0; i < buffer.length; ++i)
buffer[i] = 0.0;
double freq = 1.0; // ÷àñòîòà (pow)
for (int i = 0; i < levels; ++i)
{
// Âûçîâ add äëÿ òåêóùåãî óðîâíÿ ñ ïðàâèëüíûì ìàñøòàáèðîâàíèåì
noiseLevels[i]->add(buffer,
x * freq * xScale,
y * freq * yScale,
z * freq * zScale,
xSize, ySize, zSize,
xScale * freq,
yScale * freq,
zScale * freq,
freq);
freq *= 0.5;
}
return buffer;
}
// Ïåðåãðóçêà äëÿ 2D ðåãèîíà (y ôèêñèðîâàí)
doubleArray PerlinNoise::getRegion(doubleArray sr, int x, int z,
int xSize, int zSize,
double xScale, double zScale, double pow)
{
// Èñïîëüçóåì y = 10 (êàê â îðèãèíàëå), ySize = 1
return getRegion(sr, x, 10, z, xSize, 1, zSize, xScale, 1.0, zScale);
}