Added FastNoiseLite
This commit is contained in:
parent
3e31140ed8
commit
c8dcbc55e3
2
SCsub
2
SCsub
@ -16,6 +16,7 @@ files = [
|
||||
"generators/graph/*.cpp",
|
||||
"generators/simple/*.cpp",
|
||||
"util/*.cpp",
|
||||
"util/noise/*.cpp",
|
||||
"terrain/*.cpp",
|
||||
"server/*.cpp",
|
||||
"math/*.cpp",
|
||||
@ -29,6 +30,7 @@ if env["tools"]:
|
||||
"editor/*.cpp",
|
||||
"editor/graph/*.cpp",
|
||||
"editor/terrain/*.cpp",
|
||||
"editor/fast_noise_lite/*.cpp",
|
||||
]
|
||||
files += editor_files
|
||||
|
||||
|
185
editor/fast_noise_lite/fast_noise_lite_editor_plugin.cpp
Normal file
185
editor/fast_noise_lite/fast_noise_lite_editor_plugin.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
#include "fast_noise_lite_editor_plugin.h"
|
||||
#include "../../util/noise/fast_noise_lite.h"
|
||||
#include "../../util/noise/fast_noise_lite_gradient.h"
|
||||
|
||||
#include <core/core_string_names.h>
|
||||
#include <editor/editor_scale.h>
|
||||
|
||||
class FastNoiseLiteViewer : public Control {
|
||||
GDCLASS(FastNoiseLiteViewer, Control)
|
||||
public:
|
||||
static const int PREVIEW_WIDTH = 300;
|
||||
static const int PREVIEW_HEIGHT = 150;
|
||||
|
||||
FastNoiseLiteViewer() {
|
||||
set_custom_minimum_size(Vector2(0, EDSCALE * PREVIEW_HEIGHT));
|
||||
|
||||
_texture_rect = memnew(TextureRect);
|
||||
_texture_rect->set_anchors_and_margins_preset(Control::PRESET_WIDE);
|
||||
_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_COVERED);
|
||||
add_child(_texture_rect);
|
||||
}
|
||||
|
||||
// ~FastNoiseLiteViewer() {
|
||||
// }
|
||||
|
||||
void set_noise(Ref<FastNoiseLite> noise) {
|
||||
if (_noise == noise) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_noise.is_valid()) {
|
||||
_noise->disconnect(CoreStringNames::get_singleton()->changed, this, "_on_noise_changed");
|
||||
}
|
||||
|
||||
_noise = noise;
|
||||
|
||||
if (_noise.is_valid()) {
|
||||
set_noise_gradient(Ref<FastNoiseLiteGradient>());
|
||||
_noise->connect(CoreStringNames::get_singleton()->changed, this, "_on_noise_changed");
|
||||
set_process(true);
|
||||
update_preview();
|
||||
|
||||
} else {
|
||||
set_process(false);
|
||||
_time_before_update = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void set_noise_gradient(Ref<FastNoiseLiteGradient> noise_gradient) {
|
||||
if (_noise_gradient == noise_gradient) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_noise_gradient.is_valid()) {
|
||||
_noise_gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_on_noise_changed");
|
||||
}
|
||||
|
||||
_noise_gradient = noise_gradient;
|
||||
|
||||
if (_noise_gradient.is_valid()) {
|
||||
set_noise(Ref<FastNoiseLite>());
|
||||
_noise_gradient->connect(CoreStringNames::get_singleton()->changed, this, "_on_noise_changed");
|
||||
set_process(true);
|
||||
update_preview();
|
||||
|
||||
} else {
|
||||
set_process(false);
|
||||
_time_before_update = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void _on_noise_changed() {
|
||||
_time_before_update = 0.5f;
|
||||
}
|
||||
|
||||
void _notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_PROCESS: {
|
||||
if (_time_before_update > 0.f) {
|
||||
_time_before_update -= get_process_delta_time();
|
||||
if (_time_before_update <= 0.f) {
|
||||
update_preview();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Use thread?
|
||||
void update_preview() {
|
||||
const Vector2i preview_size(PREVIEW_WIDTH, PREVIEW_HEIGHT);
|
||||
|
||||
Ref<Image> im;
|
||||
im.instance();
|
||||
im->create(preview_size.x, preview_size.y, false, Image::FORMAT_RGB8);
|
||||
|
||||
im->lock();
|
||||
|
||||
if (_noise.is_valid()) {
|
||||
for (int y = 0; y < preview_size.y; ++y) {
|
||||
for (int x = 0; x < preview_size.x; ++x) {
|
||||
// Assuming -1..1 output. Some noise types can have different range though.
|
||||
const float v = _noise->get_noise_2d(x, y);
|
||||
const float g = 0.5f * v + 0.5f;
|
||||
im->set_pixel(x, y, Color(g, g, g));
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_noise_gradient.is_valid()) {
|
||||
const float amp = _noise_gradient->get_amplitude();
|
||||
float m = (amp == 0.f ? 1.f : 1.f / amp);
|
||||
for (int y = 0; y < preview_size.y; ++y) {
|
||||
for (int x = 0; x < preview_size.x; ++x) {
|
||||
const float x0 = x;
|
||||
const float y0 = y;
|
||||
float x1 = x0;
|
||||
float y1 = y0;
|
||||
_noise_gradient->warp_2d(x1, y1);
|
||||
const float dx = x1 - x0;
|
||||
const float dy = y1 - y0;
|
||||
const float r = 0.5f * m * dx + 0.5f;
|
||||
const float g = 0.5f * m * dy + 0.5f;
|
||||
im->set_pixel(x, y, Color(r, g, 0.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
im->unlock();
|
||||
|
||||
Ref<ImageTexture> tex;
|
||||
tex.instance();
|
||||
tex->create_from_image(im);
|
||||
_texture_rect->set_texture(tex);
|
||||
}
|
||||
|
||||
static void _bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_on_noise_changed"), &FastNoiseLiteViewer::_on_noise_changed);
|
||||
}
|
||||
|
||||
Ref<FastNoiseLite> _noise;
|
||||
Ref<FastNoiseLiteGradient> _noise_gradient;
|
||||
float _time_before_update = -1.f;
|
||||
TextureRect *_texture_rect = nullptr;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FastNoiseLiteEditorInspectorPlugin : public EditorInspectorPlugin {
|
||||
GDCLASS(FastNoiseLiteEditorInspectorPlugin, EditorInspectorPlugin)
|
||||
public:
|
||||
bool can_handle(Object *p_object) override {
|
||||
return Object::cast_to<FastNoiseLite>(p_object) != NULL ||
|
||||
Object::cast_to<FastNoiseLiteGradient>(p_object);
|
||||
}
|
||||
|
||||
void parse_begin(Object *p_object) override {
|
||||
FastNoiseLite *noise_ptr = Object::cast_to<FastNoiseLite>(p_object);
|
||||
if (noise_ptr) {
|
||||
Ref<FastNoiseLite> noise(noise_ptr);
|
||||
|
||||
FastNoiseLiteViewer *viewer = memnew(FastNoiseLiteViewer);
|
||||
viewer->set_noise(noise);
|
||||
add_custom_control(viewer);
|
||||
return;
|
||||
}
|
||||
FastNoiseLiteGradient *noise_gradient_ptr = Object::cast_to<FastNoiseLiteGradient>(p_object);
|
||||
if (noise_gradient_ptr) {
|
||||
Ref<FastNoiseLiteGradient> noise_gradient(noise_gradient_ptr);
|
||||
|
||||
FastNoiseLiteViewer *viewer = memnew(FastNoiseLiteViewer);
|
||||
viewer->set_noise_gradient(noise_gradient);
|
||||
add_custom_control(viewer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FastNoiseLiteEditorPlugin::FastNoiseLiteEditorPlugin(EditorNode *p_node) {
|
||||
Ref<FastNoiseLiteEditorInspectorPlugin> plugin;
|
||||
plugin.instance();
|
||||
add_inspector_plugin(plugin);
|
||||
}
|
14
editor/fast_noise_lite/fast_noise_lite_editor_plugin.h
Normal file
14
editor/fast_noise_lite/fast_noise_lite_editor_plugin.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef FAST_NOISE_LITE_EDITOR_PLUGIN_H
|
||||
#define FAST_NOISE_LITE_EDITOR_PLUGIN_H
|
||||
|
||||
#include <editor/editor_plugin.h>
|
||||
|
||||
class FastNoiseLiteEditorPlugin : public EditorPlugin {
|
||||
GDCLASS(FastNoiseLiteEditorPlugin, EditorPlugin)
|
||||
public:
|
||||
virtual String get_name() const { return "FastNoiseLite"; }
|
||||
|
||||
FastNoiseLiteEditorPlugin(EditorNode *p_node);
|
||||
};
|
||||
|
||||
#endif // FAST_NOISE_LITE_EDITOR_PLUGIN_H
|
@ -2,6 +2,7 @@
|
||||
#include "edition/voxel_tool.h"
|
||||
#include "edition/voxel_tool_terrain.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "editor/fast_noise_lite/fast_noise_lite_editor_plugin.h"
|
||||
#include "editor/graph/voxel_graph_editor_plugin.h"
|
||||
#include "editor/terrain/voxel_terrain_editor_plugin.h"
|
||||
#include "generators/graph/voxel_generator_graph.h"
|
||||
@ -31,7 +32,10 @@
|
||||
#include "terrain/voxel_terrain.h"
|
||||
#include "terrain/voxel_viewer.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/noise/fast_noise_lite.h"
|
||||
#include "util/noise/fast_noise_lite_gradient.h"
|
||||
#include "voxel_string_names.h"
|
||||
|
||||
#include <core/engine.h>
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
@ -87,6 +91,8 @@ void register_voxel_types() {
|
||||
ClassDB::register_class<VoxelToolTerrain>();
|
||||
ClassDB::register_class<VoxelBlockSerializer>();
|
||||
ClassDB::register_class<VoxelVoxLoader>();
|
||||
ClassDB::register_class<FastNoiseLite>();
|
||||
ClassDB::register_class<FastNoiseLiteGradient>();
|
||||
|
||||
// Meshers
|
||||
ClassDB::register_virtual_class<VoxelMesher>();
|
||||
@ -104,6 +110,7 @@ void register_voxel_types() {
|
||||
#ifdef TOOLS_ENABLED
|
||||
EditorPlugins::add_by_type<VoxelGraphEditorPlugin>();
|
||||
EditorPlugins::add_by_type<VoxelTerrainEditorPlugin>();
|
||||
EditorPlugins::add_by_type<FastNoiseLiteEditorPlugin>();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
2589
thirdparty/fast_noise/FastNoiseLite.h
vendored
Normal file
2589
thirdparty/fast_noise/FastNoiseLite.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
360
util/noise/fast_noise_lite.cpp
Normal file
360
util/noise/fast_noise_lite.cpp
Normal file
@ -0,0 +1,360 @@
|
||||
#include "fast_noise_lite.h"
|
||||
#include "../utility.h"
|
||||
|
||||
#include <core/core_string_names.h>
|
||||
|
||||
FastNoiseLite::FastNoiseLite() {
|
||||
_fn.SetNoiseType(static_cast<_FastNoise::NoiseType>(_noise_type));
|
||||
_fn.SetSeed(_seed);
|
||||
_fn.SetFrequency(1.f / _period);
|
||||
|
||||
_fn.SetFractalType(static_cast<_FastNoise::FractalType>(_fractal_type));
|
||||
_fn.SetFractalOctaves(_fractal_octaves);
|
||||
_fn.SetFractalLacunarity(_fractal_lacunarity);
|
||||
_fn.SetFractalPingPongStrength(_fractal_ping_pong_strength);
|
||||
_fn.SetFractalGain(_fractal_gain);
|
||||
_fn.SetFractalWeightedStrength(_fractal_weighted_strength);
|
||||
|
||||
_fn.SetCellularDistanceFunction(static_cast<_FastNoise::CellularDistanceFunction>(_cellular_distance_function));
|
||||
_fn.SetCellularReturnType(static_cast<_FastNoise::CellularReturnType>(_cellular_return_type));
|
||||
_fn.SetCellularJitter(_cellular_jitter);
|
||||
|
||||
_fn.SetRotationType3D(static_cast<_FastNoise::RotationType3D>(_rotation_type_3d));
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_noise_type(NoiseType type) {
|
||||
if (_noise_type == type) {
|
||||
return;
|
||||
}
|
||||
_noise_type = type;
|
||||
_fn.SetNoiseType(static_cast<_FastNoise::NoiseType>(_noise_type));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::NoiseType FastNoiseLite::get_noise_type() const {
|
||||
return _noise_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_seed(int seed) {
|
||||
if (_seed == seed) {
|
||||
return;
|
||||
}
|
||||
_seed = seed;
|
||||
_fn.SetSeed(seed);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLite::get_seed() const {
|
||||
return _seed;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_period(float p) {
|
||||
if (p < 0.0001f) {
|
||||
p = 0.0001f;
|
||||
}
|
||||
if (_period == p) {
|
||||
return;
|
||||
}
|
||||
_period = p;
|
||||
_fn.SetFrequency(1.f / _period);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_period() const {
|
||||
return _period;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_warp_noise(Ref<FastNoiseLiteGradient> warp_noise) {
|
||||
if (_warp_noise == warp_noise) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_warp_noise.is_valid()) {
|
||||
_warp_noise->disconnect(CoreStringNames::get_singleton()->changed, this, "_on_warp_noise_changed");
|
||||
}
|
||||
|
||||
_warp_noise = warp_noise;
|
||||
|
||||
if (_warp_noise.is_valid()) {
|
||||
_warp_noise->connect(CoreStringNames::get_singleton()->changed, this, "_on_warp_noise_changed");
|
||||
}
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Ref<FastNoiseLiteGradient> FastNoiseLite::get_warp_noise() const {
|
||||
return _warp_noise;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_type(FractalType type) {
|
||||
if (_fractal_type == type) {
|
||||
return;
|
||||
}
|
||||
_fractal_type = type;
|
||||
_fn.SetFractalType(static_cast<_FastNoise::FractalType>(_fractal_type));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::FractalType FastNoiseLite::get_fractal_type() const {
|
||||
return _fractal_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_octaves(int octaves) {
|
||||
ERR_FAIL_COND(octaves <= 0);
|
||||
if (octaves > _MAX_OCTAVES) {
|
||||
octaves = _MAX_OCTAVES;
|
||||
}
|
||||
if (_fractal_octaves == octaves) {
|
||||
return;
|
||||
}
|
||||
_fractal_octaves = octaves;
|
||||
_fn.SetFractalOctaves(octaves);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLite::get_fractal_octaves() const {
|
||||
return _fractal_octaves;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_lacunarity(float lacunarity) {
|
||||
if (_fractal_lacunarity == lacunarity) {
|
||||
return;
|
||||
}
|
||||
_fractal_lacunarity = lacunarity;
|
||||
_fn.SetFractalLacunarity(lacunarity);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_fractal_lacunarity() const {
|
||||
return _fractal_lacunarity;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_gain(float gain) {
|
||||
if (_fractal_gain == gain) {
|
||||
return;
|
||||
}
|
||||
_fractal_gain = gain;
|
||||
_fn.SetFractalGain(gain);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_fractal_gain() const {
|
||||
return _fractal_gain;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_ping_pong_strength(float s) {
|
||||
if (_fractal_ping_pong_strength == s) {
|
||||
return;
|
||||
}
|
||||
_fractal_ping_pong_strength = s;
|
||||
_fn.SetFractalPingPongStrength(s);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_fractal_ping_pong_strength() const {
|
||||
return _fractal_ping_pong_strength;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_weighted_strength(float s) {
|
||||
if (_fractal_weighted_strength == s) {
|
||||
return;
|
||||
}
|
||||
_fractal_weighted_strength = s;
|
||||
_fn.SetFractalWeightedStrength(s);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_fractal_weighted_strength() const {
|
||||
return _fractal_weighted_strength;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_distance_function(CellularDistanceFunction cdf) {
|
||||
if (cdf == _cellular_distance_function) {
|
||||
return;
|
||||
}
|
||||
_cellular_distance_function = cdf;
|
||||
_fn.SetCellularDistanceFunction(static_cast<_FastNoise::CellularDistanceFunction>(_cellular_distance_function));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::CellularDistanceFunction FastNoiseLite::get_cellular_distance_function() const {
|
||||
return _cellular_distance_function;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_return_type(CellularReturnType rt) {
|
||||
if (_cellular_return_type == rt) {
|
||||
return;
|
||||
}
|
||||
_cellular_return_type = rt;
|
||||
_fn.SetCellularReturnType(static_cast<_FastNoise::CellularReturnType>(_cellular_return_type));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::CellularReturnType FastNoiseLite::get_cellular_return_type() const {
|
||||
return _cellular_return_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_jitter(float jitter) {
|
||||
jitter = clamp(jitter, 0.f, 1.f);
|
||||
if (_cellular_jitter == jitter) {
|
||||
return;
|
||||
}
|
||||
_cellular_jitter = jitter;
|
||||
_fn.SetCellularJitter(_cellular_jitter);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLite::get_cellular_jitter() const {
|
||||
return _cellular_jitter;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_rotation_type_3d(RotationType3D type) {
|
||||
if (_rotation_type_3d == type) {
|
||||
return;
|
||||
}
|
||||
_rotation_type_3d = type;
|
||||
_fn.SetRotationType3D(static_cast<_FastNoise::RotationType3D>(_rotation_type_3d));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::RotationType3D FastNoiseLite::get_rotation_type_3d() const {
|
||||
return _rotation_type_3d;
|
||||
}
|
||||
|
||||
void FastNoiseLite::_on_warp_noise_changed() {
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void FastNoiseLite::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_noise_type", "type"), &FastNoiseLite::set_noise_type);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_type"), &FastNoiseLite::get_noise_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &FastNoiseLite::set_seed);
|
||||
ClassDB::bind_method(D_METHOD("get_seed"), &FastNoiseLite::get_seed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_period", "period"), &FastNoiseLite::set_period);
|
||||
ClassDB::bind_method(D_METHOD("get_period"), &FastNoiseLite::get_period);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_warp_noise", "gradient_noise"), &FastNoiseLite::set_warp_noise);
|
||||
ClassDB::bind_method(D_METHOD("get_warp_noise"), &FastNoiseLite::get_warp_noise);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_type", "type"), &FastNoiseLite::set_fractal_type);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_type"), &FastNoiseLite::get_fractal_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_octaves", "octaves"), &FastNoiseLite::set_fractal_octaves);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_octaves"), &FastNoiseLite::get_fractal_octaves);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_lacunarity", "lacunarity"), &FastNoiseLite::set_fractal_lacunarity);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_lacunarity"), &FastNoiseLite::get_fractal_lacunarity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_gain", "gain"), &FastNoiseLite::set_fractal_gain);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_gain"), &FastNoiseLite::get_fractal_gain);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_ping_pong_strength", "strength"),
|
||||
&FastNoiseLite::set_fractal_ping_pong_strength);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_ping_pong_strength"), &FastNoiseLite::get_fractal_ping_pong_strength);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_weighted_strength", "strength"),
|
||||
&FastNoiseLite::set_fractal_weighted_strength);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_weighted_strength"), &FastNoiseLite::get_fractal_weighted_strength);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cellular_distance_function", "cell_distance_func"),
|
||||
&FastNoiseLite::set_cellular_distance_function);
|
||||
ClassDB::bind_method(D_METHOD("get_cellular_distance_function"), &FastNoiseLite::get_cellular_distance_function);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cellular_return_type", "return_type"), &FastNoiseLite::set_cellular_return_type);
|
||||
ClassDB::bind_method(D_METHOD("get_cellular_return_type"), &FastNoiseLite::get_cellular_return_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cellular_jitter", "return_type"), &FastNoiseLite::set_cellular_jitter);
|
||||
ClassDB::bind_method(D_METHOD("get_cellular_jitter"), &FastNoiseLite::get_cellular_jitter);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rotation_type_3d", "type"), &FastNoiseLite::set_rotation_type_3d);
|
||||
ClassDB::bind_method(D_METHOD("get_rotation_type_3d"), &FastNoiseLite::get_rotation_type_3d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2d", "x", "y"), &FastNoiseLite::_b_get_noise_2d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_3d", "x", "y", "z"), &FastNoiseLite::_b_get_noise_3d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2dv", "position"), &FastNoiseLite::_b_get_noise_2dv);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_3dv", "position"), &FastNoiseLite::_b_get_noise_3dv);
|
||||
|
||||
// TODO This is an internal method, it should be hidden from scripts
|
||||
ClassDB::bind_method(D_METHOD("_on_warp_noise_changed"), &FastNoiseLite::_on_warp_noise_changed);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM,
|
||||
"OpenSimplex2,OpenSimplex2S,Cellular,Perlin,ValueCubic,Value"),
|
||||
"set_noise_type", "get_noise_type");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_EXP_RANGE, "0.0001,10000.0"),
|
||||
"set_period", "get_period");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "warp_noise", PROPERTY_HINT_RESOURCE_TYPE, "FastNoiseLiteGradient"),
|
||||
"set_warp_noise", "get_warp_noise");
|
||||
|
||||
ADD_GROUP("Fractal", "");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM,
|
||||
"None,FBm,Ridged,PingPong"),
|
||||
"set_fractal_type", "get_fractal_type");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", _MAX_OCTAVES)),
|
||||
"set_fractal_octaves", "get_fractal_octaves");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_lacunarity"), "set_fractal_lacunarity", "get_fractal_lacunarity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_gain"), "set_fractal_gain", "get_fractal_gain");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_ping_pong_strength"),
|
||||
"set_fractal_ping_pong_strength", "get_fractal_ping_pong_strength");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_weighted_strength"),
|
||||
"set_fractal_weighted_strength", "get_fractal_weighted_strength");
|
||||
|
||||
ADD_GROUP("Cellular", "");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_distance_function", PROPERTY_HINT_ENUM,
|
||||
"DistanceEuclidean,DistanceEuclideanSq,Manhattan,Hybrid"),
|
||||
"set_cellular_distance_function", "get_cellular_distance_function");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_return_type", PROPERTY_HINT_ENUM,
|
||||
"CellValue,Distance,Distance2,Distance2Add,Distance2Sub,Distance2Mul,Distance2Div"),
|
||||
"set_cellular_return_type", "get_cellular_return_type");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cellular_jitter", PROPERTY_HINT_RANGE, "0.0,1.0"),
|
||||
"set_cellular_jitter", "get_cellular_jitter");
|
||||
|
||||
ADD_GROUP("Advanced", "");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_type_3d", PROPERTY_HINT_ENUM,
|
||||
"None,ImproveXYPlanes,ImproveXZPlanes"),
|
||||
"set_rotation_type_3d", "get_rotation_type_3d");
|
||||
|
||||
BIND_ENUM_CONSTANT(TYPE_OPEN_SIMPLEX_2);
|
||||
BIND_ENUM_CONSTANT(TYPE_OPEN_SIMPLEX_2S);
|
||||
BIND_ENUM_CONSTANT(TYPE_CELLULAR);
|
||||
BIND_ENUM_CONSTANT(TYPE_PERLIN);
|
||||
BIND_ENUM_CONSTANT(TYPE_VALUE_CUBIC);
|
||||
BIND_ENUM_CONSTANT(TYPE_VALUE);
|
||||
|
||||
BIND_ENUM_CONSTANT(FRACTAL_NONE);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_FBM);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_RIDGED);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_PING_PONG);
|
||||
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_NONE);
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_IMPROVE_XY_PLANES);
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_IMPROVE_XZ_PLANES);
|
||||
|
||||
BIND_ENUM_CONSTANT(CELLULAR_DISTANCE_EUCLIDEAN);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_DISTANCE_EUCLIDEAN_SQ);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_DISTANCE_MANHATTAN);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_DISTANCE_HYBRID);
|
||||
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_CELL_VALUE);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE_2);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE_2_ADD);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE_2_SUB);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE_2_MUL);
|
||||
BIND_ENUM_CONSTANT(CELLULAR_RETURN_DISTANCE_2_DIV);
|
||||
}
|
158
util/noise/fast_noise_lite.h
Normal file
158
util/noise/fast_noise_lite.h
Normal file
@ -0,0 +1,158 @@
|
||||
#ifndef FAST_NOISE_LITE_H
|
||||
#define FAST_NOISE_LITE_H
|
||||
|
||||
#include <core/resource.h>
|
||||
|
||||
#include "fast_noise_lite_gradient.h"
|
||||
|
||||
class FastNoiseLite : public Resource {
|
||||
GDCLASS(FastNoiseLite, Resource)
|
||||
|
||||
typedef fast_noise_lite::FastNoiseLite _FastNoise;
|
||||
|
||||
public:
|
||||
// TODO Had to prefix it because of https://github.com/godotengine/godot/issues/44860
|
||||
static const int _MAX_OCTAVES = 32;
|
||||
|
||||
enum NoiseType {
|
||||
TYPE_OPEN_SIMPLEX_2 = _FastNoise::NoiseType_OpenSimplex2,
|
||||
TYPE_OPEN_SIMPLEX_2S = _FastNoise::NoiseType_OpenSimplex2S,
|
||||
TYPE_CELLULAR = _FastNoise::NoiseType_Cellular,
|
||||
TYPE_PERLIN = _FastNoise::NoiseType_Perlin,
|
||||
TYPE_VALUE_CUBIC = _FastNoise::NoiseType_ValueCubic,
|
||||
TYPE_VALUE = _FastNoise::NoiseType_Value
|
||||
};
|
||||
|
||||
enum FractalType {
|
||||
FRACTAL_NONE = _FastNoise::FractalType_None,
|
||||
FRACTAL_FBM = _FastNoise::FractalType_FBm,
|
||||
FRACTAL_RIDGED = _FastNoise::FractalType_Ridged,
|
||||
FRACTAL_PING_PONG = _FastNoise::FractalType_PingPong
|
||||
};
|
||||
|
||||
enum RotationType3D {
|
||||
ROTATION_3D_NONE = _FastNoise::RotationType3D_None,
|
||||
ROTATION_3D_IMPROVE_XY_PLANES = _FastNoise::RotationType3D_ImproveXYPlanes,
|
||||
ROTATION_3D_IMPROVE_XZ_PLANES = _FastNoise::RotationType3D_ImproveXZPlanes
|
||||
};
|
||||
|
||||
enum CellularDistanceFunction {
|
||||
CELLULAR_DISTANCE_EUCLIDEAN = _FastNoise::CellularDistanceFunction_Euclidean,
|
||||
CELLULAR_DISTANCE_EUCLIDEAN_SQ = _FastNoise::CellularDistanceFunction_EuclideanSq,
|
||||
CELLULAR_DISTANCE_MANHATTAN = _FastNoise::CellularDistanceFunction_Manhattan,
|
||||
CELLULAR_DISTANCE_HYBRID = _FastNoise::CellularDistanceFunction_Hybrid
|
||||
};
|
||||
|
||||
enum CellularReturnType {
|
||||
CELLULAR_RETURN_CELL_VALUE = _FastNoise::CellularReturnType_CellValue,
|
||||
CELLULAR_RETURN_DISTANCE = _FastNoise::CellularReturnType_Distance,
|
||||
CELLULAR_RETURN_DISTANCE_2 = _FastNoise::CellularReturnType_Distance2,
|
||||
CELLULAR_RETURN_DISTANCE_2_ADD = _FastNoise::CellularReturnType_Distance2Add,
|
||||
CELLULAR_RETURN_DISTANCE_2_SUB = _FastNoise::CellularReturnType_Distance2Sub,
|
||||
CELLULAR_RETURN_DISTANCE_2_MUL = _FastNoise::CellularReturnType_Distance2Mul,
|
||||
CELLULAR_RETURN_DISTANCE_2_DIV = _FastNoise::CellularReturnType_Distance2Div
|
||||
};
|
||||
|
||||
FastNoiseLite();
|
||||
|
||||
void set_noise_type(NoiseType type);
|
||||
NoiseType get_noise_type() const;
|
||||
|
||||
void set_seed(int seed);
|
||||
int get_seed() const;
|
||||
|
||||
void set_period(float p);
|
||||
float get_period() const;
|
||||
|
||||
void set_warp_noise(Ref<FastNoiseLiteGradient> warp_noise);
|
||||
Ref<FastNoiseLiteGradient> get_warp_noise() const;
|
||||
|
||||
void set_fractal_type(FractalType type);
|
||||
FractalType get_fractal_type() const;
|
||||
|
||||
void set_fractal_octaves(int octaves);
|
||||
int get_fractal_octaves() const;
|
||||
|
||||
void set_fractal_lacunarity(float lacunarity);
|
||||
float get_fractal_lacunarity() const;
|
||||
|
||||
void set_fractal_gain(float gain);
|
||||
float get_fractal_gain() const;
|
||||
|
||||
void set_fractal_ping_pong_strength(float s);
|
||||
float get_fractal_ping_pong_strength() const;
|
||||
|
||||
void set_fractal_weighted_strength(float s);
|
||||
float get_fractal_weighted_strength() const;
|
||||
|
||||
void set_cellular_distance_function(CellularDistanceFunction cdf);
|
||||
CellularDistanceFunction get_cellular_distance_function() const;
|
||||
|
||||
void set_cellular_return_type(CellularReturnType rt);
|
||||
CellularReturnType get_cellular_return_type() const;
|
||||
|
||||
void set_cellular_jitter(float jitter);
|
||||
float get_cellular_jitter() const;
|
||||
|
||||
void set_rotation_type_3d(RotationType3D type);
|
||||
RotationType3D get_rotation_type_3d() const;
|
||||
|
||||
inline float get_noise_2d(float x, float y) {
|
||||
if (_warp_noise.is_valid()) {
|
||||
_warp_noise->warp_2d(x, y);
|
||||
}
|
||||
return _fn.GetNoise(x, y);
|
||||
}
|
||||
|
||||
inline float get_noise_3d(float x, float y, float z) {
|
||||
if (_warp_noise.is_valid()) {
|
||||
_warp_noise->warp_3d(x, y, z);
|
||||
}
|
||||
return _fn.GetNoise(x, y, z);
|
||||
}
|
||||
|
||||
// TODO Bounds access
|
||||
// TODO Interval range analysis
|
||||
|
||||
private:
|
||||
static void _bind_methods();
|
||||
|
||||
void _on_warp_noise_changed();
|
||||
|
||||
float _b_get_noise_2d(float x, float y) { return get_noise_2d(x, y); }
|
||||
float _b_get_noise_3d(float x, float y, float z) { return get_noise_3d(x, y, z); }
|
||||
|
||||
float _b_get_noise_2dv(Vector2 p) { return get_noise_2d(p.x, p.y); }
|
||||
float _b_get_noise_3dv(Vector3 p) { return get_noise_3d(p.x, p.y, p.z); }
|
||||
|
||||
fast_noise_lite::FastNoiseLite _fn;
|
||||
|
||||
// TODO FastNoiseLite should rather have getters
|
||||
|
||||
NoiseType _noise_type = TYPE_OPEN_SIMPLEX_2;
|
||||
int _seed = 0;
|
||||
float _period = 64.f;
|
||||
|
||||
FractalType _fractal_type = FRACTAL_FBM;
|
||||
int _fractal_octaves = 3;
|
||||
float _fractal_lacunarity = 2.f;
|
||||
float _fractal_ping_pong_strength = 2.f;
|
||||
float _fractal_gain = 0.5f;
|
||||
float _fractal_weighted_strength = 0.f;
|
||||
|
||||
CellularDistanceFunction _cellular_distance_function = CELLULAR_DISTANCE_EUCLIDEAN_SQ;
|
||||
CellularReturnType _cellular_return_type = CELLULAR_RETURN_DISTANCE;
|
||||
float _cellular_jitter = 1.f;
|
||||
|
||||
RotationType3D _rotation_type_3d = ROTATION_3D_NONE;
|
||||
|
||||
Ref<FastNoiseLiteGradient> _warp_noise;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::NoiseType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::FractalType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::RotationType3D);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::CellularDistanceFunction);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::CellularReturnType);
|
||||
|
||||
#endif // FAST_NOISE_LITE_H
|
225
util/noise/fast_noise_lite_gradient.cpp
Normal file
225
util/noise/fast_noise_lite_gradient.cpp
Normal file
@ -0,0 +1,225 @@
|
||||
#include "fast_noise_lite_gradient.h"
|
||||
|
||||
static fast_noise_lite::FastNoiseLite::FractalType to_fnl_fractal_type(FastNoiseLiteGradient::FractalType type) {
|
||||
switch (type) {
|
||||
case FastNoiseLiteGradient::FRACTAL_NONE:
|
||||
return fast_noise_lite::FastNoiseLite::FractalType_None;
|
||||
|
||||
case FastNoiseLiteGradient::FRACTAL_DOMAIN_WARP_PROGRESSIVE:
|
||||
return fast_noise_lite::FastNoiseLite::FractalType_DomainWarpProgressive;
|
||||
|
||||
case FastNoiseLiteGradient::FRACTAL_DOMAIN_WARP_INDEPENDENT:
|
||||
return fast_noise_lite::FastNoiseLite::FractalType_DomainWarpIndependent;
|
||||
|
||||
default:
|
||||
ERR_PRINT("Unknown type");
|
||||
break;
|
||||
}
|
||||
return fast_noise_lite::FastNoiseLite::FractalType_None;
|
||||
}
|
||||
|
||||
FastNoiseLiteGradient::FastNoiseLiteGradient() {
|
||||
_fn.SetDomainWarpType(static_cast<_FastNoise::DomainWarpType>(_noise_type));
|
||||
_fn.SetSeed(_seed);
|
||||
_fn.SetFrequency(1.f / _period);
|
||||
_fn.SetDomainWarpAmp(_amplitude);
|
||||
|
||||
_fn.SetFractalType(to_fnl_fractal_type(_fractal_type));
|
||||
_fn.SetFractalOctaves(_fractal_octaves);
|
||||
_fn.SetFractalLacunarity(_fractal_lacunarity);
|
||||
_fn.SetFractalGain(_fractal_gain);
|
||||
|
||||
_fn.SetRotationType3D(static_cast<_FastNoise::RotationType3D>(_rotation_type_3d));
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_noise_type(NoiseType type) {
|
||||
if (_noise_type == type) {
|
||||
return;
|
||||
}
|
||||
_noise_type = type;
|
||||
_fn.SetDomainWarpType(static_cast<_FastNoise::DomainWarpType>(_noise_type));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLiteGradient::NoiseType FastNoiseLiteGradient::get_noise_type() const {
|
||||
return _noise_type;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_seed(int seed) {
|
||||
if (_seed == seed) {
|
||||
return;
|
||||
}
|
||||
_seed = seed;
|
||||
_fn.SetSeed(seed);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLiteGradient::get_seed() const {
|
||||
return _seed;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_period(float p) {
|
||||
if (p < 0.0001f) {
|
||||
p = 0.0001f;
|
||||
}
|
||||
if (_period == p) {
|
||||
return;
|
||||
}
|
||||
_period = p;
|
||||
_fn.SetFrequency(1.f / _period);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLiteGradient::get_period() const {
|
||||
return _period;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_amplitude(float amp) {
|
||||
if (amp == _amplitude) {
|
||||
return;
|
||||
}
|
||||
_amplitude = amp;
|
||||
_fn.SetDomainWarpAmp(amp);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLiteGradient::get_amplitude() const {
|
||||
return _amplitude;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_fractal_type(FractalType type) {
|
||||
if (type == _fractal_type) {
|
||||
return;
|
||||
}
|
||||
_fractal_type = type;
|
||||
_fn.SetFractalType(to_fnl_fractal_type(_fractal_type));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLiteGradient::FractalType FastNoiseLiteGradient::get_fractal_type() const {
|
||||
return _fractal_type;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_fractal_octaves(int octaves) {
|
||||
if (_fractal_octaves == octaves) {
|
||||
return;
|
||||
}
|
||||
_fractal_octaves = octaves;
|
||||
_fn.SetFractalOctaves(octaves);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLiteGradient::get_fractal_octaves() const {
|
||||
return _fractal_octaves;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_fractal_lacunarity(float lacunarity) {
|
||||
if (_fractal_lacunarity == lacunarity) {
|
||||
return;
|
||||
}
|
||||
_fractal_lacunarity = lacunarity;
|
||||
_fn.SetFractalLacunarity(lacunarity);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLiteGradient::get_fractal_lacunarity() const {
|
||||
return _fractal_lacunarity;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_fractal_gain(float gain) {
|
||||
if (_fractal_gain == gain) {
|
||||
return;
|
||||
}
|
||||
_fractal_gain = gain;
|
||||
_fn.SetFractalGain(gain);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
float FastNoiseLiteGradient::get_fractal_gain() const {
|
||||
return _fractal_gain;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::set_rotation_type_3d(RotationType3D type) {
|
||||
if (_rotation_type_3d == type) {
|
||||
return;
|
||||
}
|
||||
_rotation_type_3d = type;
|
||||
_fn.SetRotationType3D(static_cast<_FastNoise::RotationType3D>(_rotation_type_3d));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLiteGradient::RotationType3D FastNoiseLiteGradient::get_rotation_type_3d() const {
|
||||
return _rotation_type_3d;
|
||||
}
|
||||
|
||||
void FastNoiseLiteGradient::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_noise_type", "type"), &FastNoiseLiteGradient::set_noise_type);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_type"), &FastNoiseLiteGradient::get_noise_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &FastNoiseLiteGradient::set_seed);
|
||||
ClassDB::bind_method(D_METHOD("get_seed"), &FastNoiseLiteGradient::get_seed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_period", "period"), &FastNoiseLiteGradient::set_period);
|
||||
ClassDB::bind_method(D_METHOD("get_period"), &FastNoiseLiteGradient::get_period);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_amplitude", "amplitude"), &FastNoiseLiteGradient::set_amplitude);
|
||||
ClassDB::bind_method(D_METHOD("get_amplitude"), &FastNoiseLiteGradient::get_amplitude);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_type", "type"), &FastNoiseLiteGradient::set_fractal_type);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_type"), &FastNoiseLiteGradient::get_fractal_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_octaves", "octaves"), &FastNoiseLiteGradient::set_fractal_octaves);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_octaves"), &FastNoiseLiteGradient::get_fractal_octaves);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_lacunarity", "lacunarity"),
|
||||
&FastNoiseLiteGradient::set_fractal_lacunarity);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_lacunarity"), &FastNoiseLiteGradient::get_fractal_lacunarity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fractal_gain", "gain"), &FastNoiseLiteGradient::set_fractal_gain);
|
||||
ClassDB::bind_method(D_METHOD("get_fractal_gain"), &FastNoiseLiteGradient::get_fractal_gain);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rotation_type_3d", "type"), &FastNoiseLiteGradient::set_rotation_type_3d);
|
||||
ClassDB::bind_method(D_METHOD("get_rotation_type_3d"), &FastNoiseLiteGradient::get_rotation_type_3d);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM,
|
||||
"OpenSimplex2,OpenSimplex2Reduced,Value"),
|
||||
"set_noise_type", "get_noise_type");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_EXP_RANGE, "0.0001,10000.0"),
|
||||
"set_period", "get_period");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "amplitude", PROPERTY_HINT_EXP_RANGE, "0.0001,10000.0"),
|
||||
"set_amplitude", "get_amplitude");
|
||||
|
||||
ADD_GROUP("Fractal", "");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM,
|
||||
"None,DomainWarpProgressive,DomainWarpIndependent"),
|
||||
"set_fractal_type", "get_fractal_type");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", _MAX_OCTAVES)),
|
||||
"set_fractal_octaves", "get_fractal_octaves");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_lacunarity"), "set_fractal_lacunarity", "get_fractal_lacunarity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fractal_gain"), "set_fractal_gain", "get_fractal_gain");
|
||||
|
||||
ADD_GROUP("Advanced", "");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_type_3d", PROPERTY_HINT_ENUM,
|
||||
"None,ImproveXYPlanes,ImproveXZPlanes"),
|
||||
"set_rotation_type_3d", "get_rotation_type_3d");
|
||||
|
||||
BIND_ENUM_CONSTANT(TYPE_OPEN_SIMPLEX_2);
|
||||
BIND_ENUM_CONSTANT(TYPE_OPEN_SIMPLEX_2_REDUCED);
|
||||
BIND_ENUM_CONSTANT(TYPE_VALUE);
|
||||
|
||||
BIND_ENUM_CONSTANT(FRACTAL_NONE);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_DOMAIN_WARP_PROGRESSIVE);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_DOMAIN_WARP_INDEPENDENT);
|
||||
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_NONE);
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_IMPROVE_XY_PLANES);
|
||||
BIND_ENUM_CONSTANT(ROTATION_3D_IMPROVE_XZ_PLANES);
|
||||
}
|
124
util/noise/fast_noise_lite_gradient.h
Normal file
124
util/noise/fast_noise_lite_gradient.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifndef FAST_NOISE_LITE_GRADIENT_H
|
||||
#define FAST_NOISE_LITE_GRADIENT_H
|
||||
|
||||
#include <core/resource.h>
|
||||
|
||||
#include "../../thirdparty/fast_noise/FastNoiseLite.h"
|
||||
|
||||
// Domain warp is a transformation of coordinates before sampling the actual noise.
|
||||
// It can be done with another instance of noise, however it needs a sample for each coordinate,
|
||||
// so FastNoiseLite provides specialized versions of this using gradients.
|
||||
// This is faster and produces higher-quality results.
|
||||
//
|
||||
// Note: FastNoiseLite provides this with the same class, but then its unclear which applies to what,
|
||||
// so I made two classes, each with a specific purpose.
|
||||
//
|
||||
class FastNoiseLiteGradient : public Resource {
|
||||
GDCLASS(FastNoiseLiteGradient, Resource)
|
||||
|
||||
typedef fast_noise_lite::FastNoiseLite _FastNoise;
|
||||
|
||||
public:
|
||||
// TODO Had to prefix it because of https://github.com/godotengine/godot/issues/44860
|
||||
static const int _MAX_OCTAVES = 32;
|
||||
|
||||
enum NoiseType {
|
||||
TYPE_OPEN_SIMPLEX_2 = _FastNoise::DomainWarpType_OpenSimplex2,
|
||||
TYPE_OPEN_SIMPLEX_2_REDUCED = _FastNoise::DomainWarpType_OpenSimplex2Reduced,
|
||||
TYPE_VALUE = _FastNoise::DomainWarpType_BasicGrid
|
||||
};
|
||||
|
||||
// This one does not map directly to FastNoise unfortunately,
|
||||
// because Godot's UI wants consecutive values starting from 0...
|
||||
enum FractalType {
|
||||
FRACTAL_NONE,
|
||||
FRACTAL_DOMAIN_WARP_PROGRESSIVE,
|
||||
FRACTAL_DOMAIN_WARP_INDEPENDENT
|
||||
};
|
||||
|
||||
enum RotationType3D {
|
||||
ROTATION_3D_NONE = _FastNoise::RotationType3D_None,
|
||||
ROTATION_3D_IMPROVE_XY_PLANES = _FastNoise::RotationType3D_ImproveXYPlanes,
|
||||
ROTATION_3D_IMPROVE_XZ_PLANES = _FastNoise::RotationType3D_ImproveXZPlanes
|
||||
};
|
||||
|
||||
FastNoiseLiteGradient();
|
||||
|
||||
void set_noise_type(NoiseType type);
|
||||
NoiseType get_noise_type() const;
|
||||
|
||||
void set_seed(int seed);
|
||||
int get_seed() const;
|
||||
|
||||
void set_period(float p);
|
||||
float get_period() const;
|
||||
|
||||
void set_amplitude(float amp);
|
||||
float get_amplitude() const;
|
||||
|
||||
void set_fractal_type(FractalType type);
|
||||
FractalType get_fractal_type() const;
|
||||
|
||||
void set_fractal_octaves(int octaves);
|
||||
int get_fractal_octaves() const;
|
||||
|
||||
void set_fractal_lacunarity(float lacunarity);
|
||||
float get_fractal_lacunarity() const;
|
||||
|
||||
void set_fractal_gain(float gain);
|
||||
float get_fractal_gain() const;
|
||||
|
||||
void set_rotation_type_3d(RotationType3D type);
|
||||
RotationType3D get_rotation_type_3d() const;
|
||||
|
||||
// These are inline to ensure inlining actually happens. If they were bound directly to the script API,
|
||||
// it means they would need to have an address, in which case I'm not sure they would be inlined?
|
||||
|
||||
inline void warp_2d(float &x, float &y) {
|
||||
return _fn.DomainWarp(x, y);
|
||||
}
|
||||
|
||||
inline void warp_3d(float &x, float &y, float &z) {
|
||||
return _fn.DomainWarp(x, y, z);
|
||||
}
|
||||
|
||||
// TODO Bounds access
|
||||
// TODO Interval range analysis
|
||||
|
||||
private:
|
||||
static void _bind_methods();
|
||||
|
||||
// TODO Getting the gradient instead of adding it would be more useful?
|
||||
|
||||
Vector2 _b_warp_2d(Vector2 pos) {
|
||||
warp_2d(pos.x, pos.y);
|
||||
return pos;
|
||||
}
|
||||
|
||||
Vector3 _b_warp_3d(Vector3 pos) {
|
||||
warp_3d(pos.x, pos.y, pos.z);
|
||||
return pos;
|
||||
}
|
||||
|
||||
fast_noise_lite::FastNoiseLite _fn;
|
||||
|
||||
// TODO FastNoiseLite should rather have getters
|
||||
|
||||
NoiseType _noise_type = TYPE_VALUE;
|
||||
int _seed = 0;
|
||||
float _period = 64.f;
|
||||
float _amplitude = 30.f;
|
||||
|
||||
FractalType _fractal_type = FRACTAL_NONE;
|
||||
int _fractal_octaves = 3;
|
||||
float _fractal_lacunarity = 2.f;
|
||||
float _fractal_gain = 0.5f;
|
||||
|
||||
RotationType3D _rotation_type_3d = ROTATION_3D_NONE;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(FastNoiseLiteGradient::NoiseType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLiteGradient::FractalType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLiteGradient::RotationType3D);
|
||||
|
||||
#endif // FAST_NOISE_LITE_GRADIENT_H
|
Loading…
x
Reference in New Issue
Block a user