2014-01-01 16:45:50 +00:00
|
|
|
#include "FractalNoise.h"
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
FractalNoise::FractalNoise() {
|
2014-01-01 16:45:50 +00:00
|
|
|
scaling = 1.0;
|
|
|
|
height = 1.0;
|
|
|
|
step_scaling = 2.0;
|
|
|
|
step_height = 0.5;
|
|
|
|
slope = 0.0;
|
|
|
|
ridge = 0.0;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
FractalNoise::~FractalNoise() {
|
2014-01-21 20:51:11 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void FractalNoise::setScaling(double scaling, double height) {
|
2014-01-01 16:45:50 +00:00
|
|
|
this->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling;
|
|
|
|
this->height = scaling * height;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void FractalNoise::setStep(double scaling_factor, double height_factor) {
|
2014-01-01 16:45:50 +00:00
|
|
|
this->step_scaling = scaling_factor < 0.00000001 ? 0.0 : 1.0 / scaling_factor;
|
|
|
|
this->step_height = scaling_factor * height_factor;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void FractalNoise::setSlope(double slope_factor) {
|
2014-01-01 16:45:50 +00:00
|
|
|
this->slope = slope_factor;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void FractalNoise::setRidge(double ridge_factor) {
|
2014-01-01 16:45:50 +00:00
|
|
|
this->ridge = ridge_factor;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void FractalNoise::setState(const NoiseState &state) {
|
2014-01-01 17:21:34 +00:00
|
|
|
state.copy(&this->state);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double FractalNoise::get1d(double detail, double x) const {
|
2014-01-01 16:45:50 +00:00
|
|
|
double current_scaling = scaling;
|
|
|
|
double current_height = height;
|
|
|
|
double result = 0.0;
|
2014-01-01 17:21:34 +00:00
|
|
|
int state_level_count = state.level_offsets.size();
|
|
|
|
int i = 0;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
while (current_height >= detail) {
|
2014-01-01 17:21:34 +00:00
|
|
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
|
|
|
|
|
|
|
result += getBase1d(offset.x + x * current_scaling) * current_height;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
|
|
|
current_scaling *= step_scaling;
|
|
|
|
current_height *= step_height;
|
2014-01-01 17:21:34 +00:00
|
|
|
|
|
|
|
i++;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (i >= state_level_count) {
|
2014-01-01 17:21:34 +00:00
|
|
|
i = 0;
|
|
|
|
}
|
2014-01-01 16:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double FractalNoise::get2d(double detail, double x, double y) const {
|
2014-01-01 16:45:50 +00:00
|
|
|
double current_scaling = scaling;
|
|
|
|
double current_height = height;
|
|
|
|
double result = 0.0;
|
2014-01-01 17:21:34 +00:00
|
|
|
int state_level_count = state.level_offsets.size();
|
|
|
|
int i = 0;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
while (current_height >= detail) {
|
2014-01-01 17:21:34 +00:00
|
|
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
|
|
|
|
|
|
|
result += getBase2d(offset.x + x * current_scaling, offset.y + y * current_scaling) * current_height;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
|
|
|
current_scaling *= step_scaling;
|
|
|
|
current_height *= step_height;
|
2014-01-01 17:21:34 +00:00
|
|
|
|
|
|
|
i++;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (i >= state_level_count) {
|
2014-01-01 17:21:34 +00:00
|
|
|
i = 0;
|
|
|
|
}
|
2014-01-01 16:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double FractalNoise::get3d(double detail, double x, double y, double z) const {
|
2014-01-01 16:45:50 +00:00
|
|
|
double current_scaling = scaling;
|
|
|
|
double current_height = height;
|
|
|
|
double result = 0.0;
|
2014-01-01 17:21:34 +00:00
|
|
|
int state_level_count = state.level_offsets.size();
|
|
|
|
int i = 0;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
while (current_height >= detail) {
|
2014-01-01 17:21:34 +00:00
|
|
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
result +=
|
|
|
|
getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) *
|
|
|
|
current_height;
|
2014-01-01 16:45:50 +00:00
|
|
|
|
|
|
|
current_scaling *= step_scaling;
|
|
|
|
current_height *= step_height;
|
2014-01-01 17:21:34 +00:00
|
|
|
|
|
|
|
i++;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (i >= state_level_count) {
|
2014-01-01 17:21:34 +00:00
|
|
|
i = 0;
|
|
|
|
}
|
2014-01-01 16:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double FractalNoise::getBase1d(double x) const {
|
2014-01-01 16:45:50 +00:00
|
|
|
return getBase2d(x, 0.0);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double FractalNoise::getBase2d(double x, double y) const {
|
2014-01-01 16:45:50 +00:00
|
|
|
return getBase3d(x, y, 0.0);
|
|
|
|
}
|