Moved all generators under their own base class and folder
parent
87a9766442
commit
8879d9b2e7
1
SCsub
1
SCsub
|
@ -11,6 +11,7 @@ files = [
|
||||||
"meshers/mc/*.cpp",
|
"meshers/mc/*.cpp",
|
||||||
"meshers/*.cpp",
|
"meshers/*.cpp",
|
||||||
"streams/*.cpp",
|
"streams/*.cpp",
|
||||||
|
"generators/*.cpp",
|
||||||
"util/*.cpp",
|
"util/*.cpp",
|
||||||
"terrain/*.cpp",
|
"terrain/*.cpp",
|
||||||
"math/*.cpp",
|
"math/*.cpp",
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "voxel_generator.h"
|
||||||
|
#include "../voxel_string_names.h"
|
||||||
|
|
||||||
|
VoxelGenerator::VoxelGenerator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGenerator::generate_block(VoxelBlockRequest &input) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(input.voxel_buffer.is_null());
|
||||||
|
ScriptInstance *script = get_script_instance();
|
||||||
|
|
||||||
|
if (script) {
|
||||||
|
|
||||||
|
// Call script to generate buffer
|
||||||
|
Variant arg1 = input.voxel_buffer;
|
||||||
|
Variant arg2 = input.origin_in_voxels.to_vec3();
|
||||||
|
Variant arg3 = input.lod;
|
||||||
|
|
||||||
|
const Variant *args[3] = { &arg1, &arg2, &arg3 };
|
||||||
|
Variant::CallError err;
|
||||||
|
script->call(VoxelStringNames::get_singleton()->generate_block, args, 3, err);
|
||||||
|
|
||||||
|
ERR_FAIL_COND_MSG(err.error != Variant::CallError::CALL_OK,
|
||||||
|
"voxel_generator.cpp:emerge_block gave an error: " + String::num(err.error) +
|
||||||
|
", Argument: " + String::num(err.argument) +
|
||||||
|
", Expected type: " + Variant::get_type_name(err.expected));
|
||||||
|
|
||||||
|
// This had to be explicitely logged due to the usual GD debugger not working with threads
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//bool VoxelGenerator::is_thread_safe() const {
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//bool VoxelGenerator::is_cloneable() const {
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
void VoxelGenerator::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {
|
||||||
|
VoxelBlockRequest r = { out_buffer, Vector3i(origin_in_voxels), lod };
|
||||||
|
generate_block(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGenerator::_b_generate_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod) {
|
||||||
|
ERR_FAIL_COND(lod < 0);
|
||||||
|
VoxelBlockRequest r = { out_buffer, Vector3i(origin_in_voxels), lod };
|
||||||
|
generate_block(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGenerator::_bind_methods() {
|
||||||
|
// Note: C++ inheriting classes don't need to re-bind these, because they are bindings that call the actual virtual methods
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("generate_block", "out_buffer", "origin_in_voxels", "lod"), &VoxelGenerator::_b_generate_block);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef VOXEL_GENERATOR_H
|
||||||
|
#define VOXEL_GENERATOR_H
|
||||||
|
|
||||||
|
#include "../streams/voxel_stream.h"
|
||||||
|
|
||||||
|
// TODO I would like VoxelGenerator to not inherit VoxelStream
|
||||||
|
// because it gets members that make no sense with generators
|
||||||
|
|
||||||
|
// Provides access to read-only generated voxels.
|
||||||
|
// Must be implemented in a multi-thread-safe way.
|
||||||
|
class VoxelGenerator : public VoxelStream {
|
||||||
|
GDCLASS(VoxelGenerator, VoxelStream)
|
||||||
|
public:
|
||||||
|
VoxelGenerator();
|
||||||
|
|
||||||
|
virtual void generate_block(VoxelBlockRequest &input);
|
||||||
|
// TODO Single sample
|
||||||
|
|
||||||
|
// virtual bool is_thread_safe() const;
|
||||||
|
// virtual bool is_cloneable() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
void _b_generate_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VOXEL_GENERATOR_H
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "voxel_stream_heightmap.h"
|
||||||
|
#include "../util/array_slice.h"
|
||||||
|
#include "../util/fixed_array.h"
|
||||||
|
|
||||||
|
VoxelGeneratorHeightmap::VoxelGeneratorHeightmap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorHeightmap::set_channel(VoxelBuffer::ChannelId channel) {
|
||||||
|
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
|
||||||
|
_channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoxelBuffer::ChannelId VoxelGeneratorHeightmap::get_channel() const {
|
||||||
|
return _channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorHeightmap::set_height_start(float start) {
|
||||||
|
_range.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VoxelGeneratorHeightmap::get_height_start() const {
|
||||||
|
return _range.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorHeightmap::set_height_range(float range) {
|
||||||
|
_range.height = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VoxelGeneratorHeightmap::get_height_range() const {
|
||||||
|
return _range.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorHeightmap::set_iso_scale(float iso_scale) {
|
||||||
|
_iso_scale = iso_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VoxelGeneratorHeightmap::get_iso_scale() const {
|
||||||
|
return _iso_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorHeightmap::_bind_methods() {
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelGeneratorHeightmap::set_channel);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelGeneratorHeightmap::get_channel);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_height_start", "start"), &VoxelGeneratorHeightmap::set_height_start);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_height_start"), &VoxelGeneratorHeightmap::get_height_start);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_height_range", "range"), &VoxelGeneratorHeightmap::set_height_range);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_height_range"), &VoxelGeneratorHeightmap::get_height_range);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_iso_scale", "scale"), &VoxelGeneratorHeightmap::set_iso_scale);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_iso_scale"), &VoxelGeneratorHeightmap::get_iso_scale);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel", PROPERTY_HINT_ENUM, VoxelBuffer::CHANNEL_ID_HINT_STRING), "set_channel", "get_channel");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_start"), "set_height_start", "get_height_start");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_range"), "set_height_range", "get_height_range");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "iso_scale"), "set_iso_scale", "get_iso_scale");
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
#ifndef VOXEL_STREAM_HEIGHTMAP_H
|
#ifndef VOXEL_STREAM_HEIGHTMAP_H
|
||||||
#define VOXEL_STREAM_HEIGHTMAP_H
|
#define VOXEL_STREAM_HEIGHTMAP_H
|
||||||
|
|
||||||
#include "voxel_stream.h"
|
#include "../voxel_buffer.h"
|
||||||
|
#include "voxel_generator.h"
|
||||||
#include <core/image.h>
|
#include <core/image.h>
|
||||||
|
|
||||||
class VoxelStreamHeightmap : public VoxelStream {
|
class VoxelGeneratorHeightmap : public VoxelGenerator {
|
||||||
GDCLASS(VoxelStreamHeightmap, VoxelStream)
|
GDCLASS(VoxelGeneratorHeightmap, VoxelGenerator)
|
||||||
public:
|
public:
|
||||||
VoxelStreamHeightmap();
|
VoxelGeneratorHeightmap();
|
||||||
|
|
||||||
void set_channel(VoxelBuffer::ChannelId channel);
|
void set_channel(VoxelBuffer::ChannelId channel);
|
||||||
VoxelBuffer::ChannelId get_channel() const;
|
VoxelBuffer::ChannelId get_channel() const;
|
|
@ -19,42 +19,42 @@ inline float get_height_blurred(Image &im, int x, int y) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
VoxelStreamImage::VoxelStreamImage() {
|
VoxelGeneratorImage::VoxelGeneratorImage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamImage::set_image(Ref<Image> im) {
|
void VoxelGeneratorImage::set_image(Ref<Image> im) {
|
||||||
_image = im;
|
_image = im;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Image> VoxelStreamImage::get_image() const {
|
Ref<Image> VoxelGeneratorImage::get_image() const {
|
||||||
return _image;
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamImage::set_blur_enabled(bool enable) {
|
void VoxelGeneratorImage::set_blur_enabled(bool enable) {
|
||||||
_blur_enabled = enable;
|
_blur_enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelStreamImage::is_blur_enabled() const {
|
bool VoxelGeneratorImage::is_blur_enabled() const {
|
||||||
return _blur_enabled;
|
return _blur_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod) {
|
void VoxelGeneratorImage::generate_block(VoxelBlockRequest &input) {
|
||||||
|
|
||||||
ERR_FAIL_COND(_image.is_null());
|
ERR_FAIL_COND(_image.is_null());
|
||||||
|
|
||||||
VoxelBuffer &out_buffer = **p_out_buffer;
|
VoxelBuffer &out_buffer = **input.voxel_buffer;
|
||||||
Image &image = **_image;
|
Image &image = **_image;
|
||||||
|
|
||||||
image.lock();
|
image.lock();
|
||||||
|
|
||||||
if (_blur_enabled) {
|
if (_blur_enabled) {
|
||||||
VoxelStreamHeightmap::generate(out_buffer,
|
VoxelGeneratorHeightmap::generate(out_buffer,
|
||||||
[&image](int x, int z) { return get_height_blurred(image, x, z); },
|
[&image](int x, int z) { return get_height_blurred(image, x, z); },
|
||||||
origin_in_voxels, lod);
|
input.origin_in_voxels, input.lod);
|
||||||
} else {
|
} else {
|
||||||
VoxelStreamHeightmap::generate(out_buffer,
|
VoxelGeneratorHeightmap::generate(out_buffer,
|
||||||
[&image](int x, int z) { return get_height_repeat(image, x, z); },
|
[&image](int x, int z) { return get_height_repeat(image, x, z); },
|
||||||
origin_in_voxels, lod);
|
input.origin_in_voxels, input.lod);
|
||||||
}
|
}
|
||||||
|
|
||||||
image.unlock();
|
image.unlock();
|
||||||
|
@ -62,10 +62,12 @@ void VoxelStreamImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i orig
|
||||||
out_buffer.compress_uniform_channels();
|
out_buffer.compress_uniform_channels();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamImage::_bind_methods() {
|
void VoxelGeneratorImage::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_image", "image"), &VoxelStreamImage::set_image);
|
ClassDB::bind_method(D_METHOD("set_image", "image"), &VoxelGeneratorImage::set_image);
|
||||||
ClassDB::bind_method(D_METHOD("get_image"), &VoxelStreamImage::get_image);
|
ClassDB::bind_method(D_METHOD("get_image"), &VoxelGeneratorImage::get_image);
|
||||||
|
|
||||||
|
// TODO Expose blur option!
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_image", "get_image");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_image", "get_image");
|
||||||
}
|
}
|
|
@ -5,10 +5,10 @@
|
||||||
#include <core/image.h>
|
#include <core/image.h>
|
||||||
|
|
||||||
// Provides infinite tiling heightmap based on an image
|
// Provides infinite tiling heightmap based on an image
|
||||||
class VoxelStreamImage : public VoxelStreamHeightmap {
|
class VoxelGeneratorImage : public VoxelGeneratorHeightmap {
|
||||||
GDCLASS(VoxelStreamImage, VoxelStreamHeightmap)
|
GDCLASS(VoxelGeneratorImage, VoxelGeneratorHeightmap)
|
||||||
public:
|
public:
|
||||||
VoxelStreamImage();
|
VoxelGeneratorImage();
|
||||||
|
|
||||||
void set_image(Ref<Image> im);
|
void set_image(Ref<Image> im);
|
||||||
Ref<Image> get_image() const;
|
Ref<Image> get_image() const;
|
||||||
|
@ -16,7 +16,7 @@ public:
|
||||||
void set_blur_enabled(bool enable);
|
void set_blur_enabled(bool enable);
|
||||||
bool is_blur_enabled() const;
|
bool is_blur_enabled() const;
|
||||||
|
|
||||||
void emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod);
|
void generate_block(VoxelBlockRequest &input) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
|
@ -1,38 +1,38 @@
|
||||||
#include "voxel_stream_noise.h"
|
#include "voxel_stream_noise.h"
|
||||||
|
|
||||||
void VoxelStreamNoise::set_channel(VoxelBuffer::ChannelId channel) {
|
void VoxelGeneratorNoise::set_channel(VoxelBuffer::ChannelId channel) {
|
||||||
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
|
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelBuffer::ChannelId VoxelStreamNoise::get_channel() const {
|
VoxelBuffer::ChannelId VoxelGeneratorNoise::get_channel() const {
|
||||||
return _channel;
|
return _channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamNoise::set_noise(Ref<OpenSimplexNoise> noise) {
|
void VoxelGeneratorNoise::set_noise(Ref<OpenSimplexNoise> noise) {
|
||||||
_noise = noise;
|
_noise = noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<OpenSimplexNoise> VoxelStreamNoise::get_noise() const {
|
Ref<OpenSimplexNoise> VoxelGeneratorNoise::get_noise() const {
|
||||||
return _noise;
|
return _noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamNoise::set_height_start(real_t y) {
|
void VoxelGeneratorNoise::set_height_start(real_t y) {
|
||||||
_height_start = y;
|
_height_start = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t VoxelStreamNoise::get_height_start() const {
|
real_t VoxelGeneratorNoise::get_height_start() const {
|
||||||
return _height_start;
|
return _height_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamNoise::set_height_range(real_t hrange) {
|
void VoxelGeneratorNoise::set_height_range(real_t hrange) {
|
||||||
if (hrange < 0.1f) {
|
if (hrange < 0.1f) {
|
||||||
hrange = 0.1f;
|
hrange = 0.1f;
|
||||||
}
|
}
|
||||||
_height_range = hrange;
|
_height_range = hrange;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t VoxelStreamNoise::get_height_range() const {
|
real_t VoxelGeneratorNoise::get_height_range() const {
|
||||||
return _height_range;
|
return _height_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +70,15 @@ static inline float get_shaped_noise(OpenSimplexNoise &noise, float x, float y,
|
||||||
return sum / max;
|
return sum / max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamNoise::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {
|
void VoxelGeneratorNoise::generate_block(VoxelBlockRequest &input) {
|
||||||
|
|
||||||
ERR_FAIL_COND(out_buffer.is_null());
|
ERR_FAIL_COND(input.voxel_buffer.is_null());
|
||||||
ERR_FAIL_COND(_noise.is_null());
|
ERR_FAIL_COND(_noise.is_null());
|
||||||
|
|
||||||
OpenSimplexNoise &noise = **_noise;
|
OpenSimplexNoise &noise = **_noise;
|
||||||
VoxelBuffer &buffer = **out_buffer;
|
VoxelBuffer &buffer = **input.voxel_buffer;
|
||||||
|
Vector3i origin_in_voxels = input.origin_in_voxels;
|
||||||
|
int lod = input.lod;
|
||||||
|
|
||||||
int isosurface_lower_bound = static_cast<int>(Math::floor(_height_start));
|
int isosurface_lower_bound = static_cast<int>(Math::floor(_height_start));
|
||||||
int isosurface_upper_bound = static_cast<int>(Math::ceil(_height_start + _height_range));
|
int isosurface_upper_bound = static_cast<int>(Math::ceil(_height_start + _height_range));
|
||||||
|
@ -157,19 +159,19 @@ void VoxelStreamNoise::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamNoise::_bind_methods() {
|
void VoxelGeneratorNoise::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &VoxelStreamNoise::set_noise);
|
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &VoxelGeneratorNoise::set_noise);
|
||||||
ClassDB::bind_method(D_METHOD("get_noise"), &VoxelStreamNoise::get_noise);
|
ClassDB::bind_method(D_METHOD("get_noise"), &VoxelGeneratorNoise::get_noise);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_height_start", "hstart"), &VoxelStreamNoise::set_height_start);
|
ClassDB::bind_method(D_METHOD("set_height_start", "hstart"), &VoxelGeneratorNoise::set_height_start);
|
||||||
ClassDB::bind_method(D_METHOD("get_height_start"), &VoxelStreamNoise::get_height_start);
|
ClassDB::bind_method(D_METHOD("get_height_start"), &VoxelGeneratorNoise::get_height_start);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_height_range", "hrange"), &VoxelStreamNoise::set_height_range);
|
ClassDB::bind_method(D_METHOD("set_height_range", "hrange"), &VoxelGeneratorNoise::set_height_range);
|
||||||
ClassDB::bind_method(D_METHOD("get_height_range"), &VoxelStreamNoise::get_height_range);
|
ClassDB::bind_method(D_METHOD("get_height_range"), &VoxelGeneratorNoise::get_height_range);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelStreamNoise::set_channel);
|
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelGeneratorNoise::set_channel);
|
||||||
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelStreamNoise::get_channel);
|
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelGeneratorNoise::get_channel);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_start"), "set_height_start", "get_height_start");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_start"), "set_height_start", "get_height_start");
|
|
@ -2,11 +2,11 @@
|
||||||
#define VOXEL_STREAM_NOISE_H
|
#define VOXEL_STREAM_NOISE_H
|
||||||
|
|
||||||
#include "../util/float_buffer_3d.h"
|
#include "../util/float_buffer_3d.h"
|
||||||
#include "voxel_stream.h"
|
#include "voxel_generator.h"
|
||||||
#include <modules/opensimplex/open_simplex_noise.h>
|
#include <modules/opensimplex/open_simplex_noise.h>
|
||||||
|
|
||||||
class VoxelStreamNoise : public VoxelStream {
|
class VoxelGeneratorNoise : public VoxelGenerator {
|
||||||
GDCLASS(VoxelStreamNoise, VoxelStream)
|
GDCLASS(VoxelGeneratorNoise, VoxelGenerator)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_channel(VoxelBuffer::ChannelId channel);
|
void set_channel(VoxelBuffer::ChannelId channel);
|
||||||
|
@ -21,7 +21,7 @@ public:
|
||||||
void set_height_range(real_t hrange);
|
void set_height_range(real_t hrange);
|
||||||
real_t get_height_range() const;
|
real_t get_height_range() const;
|
||||||
|
|
||||||
void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod);
|
void generate_block(VoxelBlockRequest &input) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "voxel_stream_noise_2d.h"
|
||||||
|
|
||||||
|
VoxelGeneratorNoise2D::VoxelGeneratorNoise2D() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorNoise2D::set_noise(Ref<OpenSimplexNoise> noise) {
|
||||||
|
_noise = noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<OpenSimplexNoise> VoxelGeneratorNoise2D::get_noise() const {
|
||||||
|
return _noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorNoise2D::set_curve(Ref<Curve> curve) {
|
||||||
|
_curve = curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Curve> VoxelGeneratorNoise2D::get_curve() const {
|
||||||
|
return _curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorNoise2D::generate_block(VoxelBlockRequest &input) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(_noise.is_null());
|
||||||
|
|
||||||
|
VoxelBuffer &out_buffer = **input.voxel_buffer;
|
||||||
|
OpenSimplexNoise &noise = **_noise;
|
||||||
|
|
||||||
|
if (_curve.is_null()) {
|
||||||
|
VoxelGeneratorHeightmap::generate(out_buffer,
|
||||||
|
[&noise](int x, int z) { return 0.5 + 0.5 * noise.get_noise_2d(x, z); },
|
||||||
|
input.origin_in_voxels, input.lod);
|
||||||
|
} else {
|
||||||
|
Curve &curve = **_curve;
|
||||||
|
VoxelGeneratorHeightmap::generate(out_buffer,
|
||||||
|
[&noise, &curve](int x, int z) { return curve.interpolate_baked(0.5 + 0.5 * noise.get_noise_2d(x, z)); },
|
||||||
|
input.origin_in_voxels, input.lod);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buffer.compress_uniform_channels();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelGeneratorNoise2D::_bind_methods() {
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &VoxelGeneratorNoise2D::set_noise);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_noise"), &VoxelGeneratorNoise2D::get_noise);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &VoxelGeneratorNoise2D::set_curve);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_curve"), &VoxelGeneratorNoise2D::get_curve);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
|
||||||
|
}
|
|
@ -4,10 +4,10 @@
|
||||||
#include "voxel_stream_heightmap.h"
|
#include "voxel_stream_heightmap.h"
|
||||||
#include <modules/opensimplex/open_simplex_noise.h>
|
#include <modules/opensimplex/open_simplex_noise.h>
|
||||||
|
|
||||||
class VoxelStreamNoise2D : public VoxelStreamHeightmap {
|
class VoxelGeneratorNoise2D : public VoxelGeneratorHeightmap {
|
||||||
GDCLASS(VoxelStreamNoise2D, VoxelStreamHeightmap)
|
GDCLASS(VoxelGeneratorNoise2D, VoxelGeneratorHeightmap)
|
||||||
public:
|
public:
|
||||||
VoxelStreamNoise2D();
|
VoxelGeneratorNoise2D();
|
||||||
|
|
||||||
void set_noise(Ref<OpenSimplexNoise> noise);
|
void set_noise(Ref<OpenSimplexNoise> noise);
|
||||||
Ref<OpenSimplexNoise> get_noise() const;
|
Ref<OpenSimplexNoise> get_noise() const;
|
||||||
|
@ -15,7 +15,7 @@ public:
|
||||||
void set_curve(Ref<Curve> curve);
|
void set_curve(Ref<Curve> curve);
|
||||||
Ref<Curve> get_curve() const;
|
Ref<Curve> get_curve() const;
|
||||||
|
|
||||||
void emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod);
|
void generate_block(VoxelBlockRequest &input) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
|
@ -1,38 +1,39 @@
|
||||||
#include "voxel_stream_test.h"
|
#include "voxel_stream_test.h"
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(VoxelStreamTest::Mode)
|
VARIANT_ENUM_CAST(VoxelGeneratorTest::Mode)
|
||||||
|
|
||||||
VoxelStreamTest::VoxelStreamTest() {
|
VoxelGeneratorTest::VoxelGeneratorTest() {
|
||||||
_mode = MODE_WAVES;
|
_mode = MODE_WAVES;
|
||||||
_voxel_type = 1;
|
_voxel_type = 1;
|
||||||
_pattern_size = Vector3i(10, 10, 10);
|
_pattern_size = Vector3i(10, 10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::set_mode(Mode mode) {
|
void VoxelGeneratorTest::set_mode(Mode mode) {
|
||||||
|
ERR_FAIL_INDEX(mode, MODE_COUNT)
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::set_voxel_type(int t) {
|
void VoxelGeneratorTest::set_voxel_type(int t) {
|
||||||
_voxel_type = t;
|
_voxel_type = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelStreamTest::get_voxel_type() const {
|
int VoxelGeneratorTest::get_voxel_type() const {
|
||||||
return _voxel_type;
|
return _voxel_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::set_pattern_size(Vector3i size) {
|
void VoxelGeneratorTest::set_pattern_size(Vector3i size) {
|
||||||
ERR_FAIL_COND(size.x < 1 || size.y < 1 || size.z < 1);
|
ERR_FAIL_COND(size.x < 1 || size.y < 1 || size.z < 1);
|
||||||
_pattern_size = size;
|
_pattern_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::set_pattern_offset(Vector3i offset) {
|
void VoxelGeneratorTest::set_pattern_offset(Vector3i offset) {
|
||||||
_pattern_offset = offset;
|
_pattern_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin, int lod) {
|
void VoxelGeneratorTest::generate_block(VoxelBlockRequest &input) {
|
||||||
ERR_FAIL_COND(out_buffer.is_null());
|
ERR_FAIL_COND(input.voxel_buffer.is_null());
|
||||||
|
|
||||||
if (lod != 0) {
|
if (input.lod != 0) {
|
||||||
// TODO Handle higher lods
|
// TODO Handle higher lods
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -40,16 +41,16 @@ void VoxelStreamTest::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin,
|
||||||
switch (_mode) {
|
switch (_mode) {
|
||||||
|
|
||||||
case MODE_FLAT:
|
case MODE_FLAT:
|
||||||
generate_block_flat(**out_buffer, origin, lod);
|
generate_block_flat(**input.voxel_buffer, input.origin_in_voxels, input.lod);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODE_WAVES:
|
case MODE_WAVES:
|
||||||
generate_block_waves(**out_buffer, origin, lod);
|
generate_block_waves(**input.voxel_buffer, input.origin_in_voxels, input.lod);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
void VoxelGeneratorTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
||||||
|
|
||||||
// TODO Don't expect a block pos, but a voxel pos!
|
// TODO Don't expect a block pos, but a voxel pos!
|
||||||
Vector3i size = out_buffer.get_size();
|
Vector3i size = out_buffer.get_size();
|
||||||
|
@ -67,7 +68,7 @@ void VoxelStreamTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i orig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
void VoxelGeneratorTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
|
||||||
|
|
||||||
// TODO Don't expect a block pos, but a voxel pos!
|
// TODO Don't expect a block pos, but a voxel pos!
|
||||||
Vector3i size = out_buffer.get_size();
|
Vector3i size = out_buffer.get_size();
|
||||||
|
@ -108,19 +109,19 @@ void VoxelStreamTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i ori
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamTest::_bind_methods() {
|
void VoxelGeneratorTest::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VoxelStreamTest::set_mode);
|
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VoxelGeneratorTest::set_mode);
|
||||||
ClassDB::bind_method(D_METHOD("get_mode"), &VoxelStreamTest::get_mode);
|
ClassDB::bind_method(D_METHOD("get_mode"), &VoxelGeneratorTest::get_mode);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_voxel_type", "id"), &VoxelStreamTest::set_voxel_type);
|
ClassDB::bind_method(D_METHOD("set_voxel_type", "id"), &VoxelGeneratorTest::set_voxel_type);
|
||||||
ClassDB::bind_method(D_METHOD("get_voxel_type"), &VoxelStreamTest::get_voxel_type);
|
ClassDB::bind_method(D_METHOD("get_voxel_type"), &VoxelGeneratorTest::get_voxel_type);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_pattern_size", "size"), &VoxelStreamTest::_set_pattern_size);
|
ClassDB::bind_method(D_METHOD("set_pattern_size", "size"), &VoxelGeneratorTest::_set_pattern_size);
|
||||||
ClassDB::bind_method(D_METHOD("get_pattern_size"), &VoxelStreamTest::_get_pattern_size);
|
ClassDB::bind_method(D_METHOD("get_pattern_size"), &VoxelGeneratorTest::_get_pattern_size);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_pattern_offset", "offset"), &VoxelStreamTest::_set_pattern_offset);
|
ClassDB::bind_method(D_METHOD("set_pattern_offset", "offset"), &VoxelGeneratorTest::_set_pattern_offset);
|
||||||
ClassDB::bind_method(D_METHOD("get_pattern_offset"), &VoxelStreamTest::_get_pattern_offset);
|
ClassDB::bind_method(D_METHOD("get_pattern_offset"), &VoxelGeneratorTest::_get_pattern_offset);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Flat,Waves"), "set_mode", "get_mode");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Flat,Waves"), "set_mode", "get_mode");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_type", PROPERTY_HINT_RANGE, "0,255,1"), "set_voxel_type", "get_voxel_type");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_type", PROPERTY_HINT_RANGE, "0,255,1"), "set_voxel_type", "get_voxel_type");
|
|
@ -1,20 +1,21 @@
|
||||||
#ifndef VOXEL_STREAM_TEST_H
|
#ifndef VOXEL_STREAM_TEST_H
|
||||||
#define VOXEL_STREAM_TEST_H
|
#define VOXEL_STREAM_TEST_H
|
||||||
|
|
||||||
#include "voxel_stream.h"
|
#include "voxel_generator.h"
|
||||||
|
|
||||||
class VoxelStreamTest : public VoxelStream {
|
class VoxelGeneratorTest : public VoxelGenerator {
|
||||||
GDCLASS(VoxelStreamTest, VoxelStream)
|
GDCLASS(VoxelGeneratorTest, VoxelGenerator)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Mode {
|
enum Mode {
|
||||||
MODE_FLAT,
|
MODE_FLAT,
|
||||||
MODE_WAVES
|
MODE_WAVES,
|
||||||
|
MODE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
VoxelStreamTest();
|
VoxelGeneratorTest();
|
||||||
|
|
||||||
virtual void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin, int lod);
|
void generate_block(VoxelBlockRequest &input) override;
|
||||||
|
|
||||||
void set_mode(Mode mode);
|
void set_mode(Mode mode);
|
||||||
Mode get_mode() const { return _mode; }
|
Mode get_mode() const { return _mode; }
|
|
@ -1,16 +1,16 @@
|
||||||
#include "register_types.h"
|
#include "register_types.h"
|
||||||
#include "edition/voxel_tool.h"
|
#include "edition/voxel_tool.h"
|
||||||
|
#include "generators/voxel_stream_heightmap.h"
|
||||||
|
#include "generators/voxel_stream_image.h"
|
||||||
|
#include "generators/voxel_stream_noise.h"
|
||||||
|
#include "generators/voxel_stream_noise_2d.h"
|
||||||
|
#include "generators/voxel_stream_test.h"
|
||||||
#include "meshers/blocky/voxel_mesher_blocky.h"
|
#include "meshers/blocky/voxel_mesher_blocky.h"
|
||||||
#include "meshers/dmc/voxel_mesher_dmc.h"
|
#include "meshers/dmc/voxel_mesher_dmc.h"
|
||||||
#include "meshers/transvoxel/voxel_mesher_transvoxel.h"
|
#include "meshers/transvoxel/voxel_mesher_transvoxel.h"
|
||||||
#include "streams/voxel_stream_block_files.h"
|
#include "streams/voxel_stream_block_files.h"
|
||||||
#include "streams/voxel_stream_file.h"
|
#include "streams/voxel_stream_file.h"
|
||||||
#include "streams/voxel_stream_heightmap.h"
|
|
||||||
#include "streams/voxel_stream_image.h"
|
|
||||||
#include "streams/voxel_stream_noise.h"
|
|
||||||
#include "streams/voxel_stream_noise_2d.h"
|
|
||||||
#include "streams/voxel_stream_region_files.h"
|
#include "streams/voxel_stream_region_files.h"
|
||||||
#include "streams/voxel_stream_test.h"
|
|
||||||
#include "terrain/voxel_box_mover.h"
|
#include "terrain/voxel_box_mover.h"
|
||||||
#include "terrain/voxel_lod_terrain.h"
|
#include "terrain/voxel_lod_terrain.h"
|
||||||
#include "terrain/voxel_map.h"
|
#include "terrain/voxel_map.h"
|
||||||
|
@ -36,15 +36,18 @@ void register_voxel_types() {
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
ClassDB::register_class<VoxelStream>();
|
ClassDB::register_class<VoxelStream>();
|
||||||
ClassDB::register_class<VoxelStreamTest>();
|
|
||||||
ClassDB::register_class<VoxelStreamHeightmap>();
|
|
||||||
ClassDB::register_class<VoxelStreamImage>();
|
|
||||||
ClassDB::register_class<VoxelStreamNoise>();
|
|
||||||
ClassDB::register_class<VoxelStreamNoise2D>();
|
|
||||||
ClassDB::register_class<VoxelStreamFile>();
|
ClassDB::register_class<VoxelStreamFile>();
|
||||||
ClassDB::register_class<VoxelStreamBlockFiles>();
|
ClassDB::register_class<VoxelStreamBlockFiles>();
|
||||||
ClassDB::register_class<VoxelStreamRegionFiles>();
|
ClassDB::register_class<VoxelStreamRegionFiles>();
|
||||||
|
|
||||||
|
// Generators
|
||||||
|
ClassDB::register_class<VoxelGenerator>();
|
||||||
|
ClassDB::register_class<VoxelGeneratorTest>();
|
||||||
|
ClassDB::register_class<VoxelGeneratorHeightmap>();
|
||||||
|
ClassDB::register_class<VoxelGeneratorImage>();
|
||||||
|
ClassDB::register_class<VoxelGeneratorNoise2D>();
|
||||||
|
ClassDB::register_class<VoxelGeneratorNoise>();
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
ClassDB::register_class<VoxelBoxMover>();
|
ClassDB::register_class<VoxelBoxMover>();
|
||||||
ClassDB::register_class<VoxelRaycastResult>();
|
ClassDB::register_class<VoxelRaycastResult>();
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef VOXEL_BLOCK_REQUEST_H
|
||||||
|
#define VOXEL_BLOCK_REQUEST_H
|
||||||
|
|
||||||
|
#include "../math/vector3i.h"
|
||||||
|
#include "../voxel_buffer.h"
|
||||||
|
|
||||||
|
class VoxelBuffer;
|
||||||
|
|
||||||
|
struct VoxelBlockRequest {
|
||||||
|
Ref<VoxelBuffer> voxel_buffer;
|
||||||
|
Vector3i origin_in_voxels;
|
||||||
|
int lod;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VOXEL_BLOCK_REQUEST_H
|
|
@ -43,17 +43,17 @@ void VoxelStream::immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStream::emerge_blocks(Vector<VoxelStream::BlockRequest> &p_blocks) {
|
void VoxelStream::emerge_blocks(Vector<VoxelBlockRequest> &p_blocks) {
|
||||||
// Default implementation. May matter for some stream types to optimize loading.
|
// Default implementation. May matter for some stream types to optimize loading.
|
||||||
for (int i = 0; i < p_blocks.size(); ++i) {
|
for (int i = 0; i < p_blocks.size(); ++i) {
|
||||||
BlockRequest &r = p_blocks.write[i];
|
VoxelBlockRequest &r = p_blocks.write[i];
|
||||||
emerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
emerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStream::immerge_blocks(Vector<VoxelStream::BlockRequest> &p_blocks) {
|
void VoxelStream::immerge_blocks(Vector<VoxelBlockRequest> &p_blocks) {
|
||||||
for (int i = 0; i < p_blocks.size(); ++i) {
|
for (int i = 0; i < p_blocks.size(); ++i) {
|
||||||
BlockRequest &r = p_blocks.write[i];
|
VoxelBlockRequest &r = p_blocks.write[i];
|
||||||
immerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
immerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,20 +2,15 @@
|
||||||
#define VOXEL_STREAM_H
|
#define VOXEL_STREAM_H
|
||||||
|
|
||||||
#include "../util/zprofiling.h"
|
#include "../util/zprofiling.h"
|
||||||
#include "../voxel_buffer.h"
|
#include "voxel_block_request.h"
|
||||||
#include <core/resource.h>
|
#include <core/resource.h>
|
||||||
|
|
||||||
// Provides access to a source of paged voxel data.
|
// Provides access to a source of paged voxel data, which may load and save.
|
||||||
// Must be implemented in a multi-thread-safe way.
|
// Must be implemented in a multi-thread-safe way.
|
||||||
|
// If you are looking for a more specialized API to generate voxels, use VoxelGenerator.
|
||||||
class VoxelStream : public Resource {
|
class VoxelStream : public Resource {
|
||||||
GDCLASS(VoxelStream, Resource)
|
GDCLASS(VoxelStream, Resource)
|
||||||
public:
|
public:
|
||||||
struct BlockRequest {
|
|
||||||
Ref<VoxelBuffer> voxel_buffer;
|
|
||||||
Vector3i origin_in_voxels;
|
|
||||||
int lod;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Stats {
|
struct Stats {
|
||||||
int file_openings = 0;
|
int file_openings = 0;
|
||||||
int time_spent_opening_files = 0;
|
int time_spent_opening_files = 0;
|
||||||
|
@ -31,12 +26,12 @@ public:
|
||||||
virtual void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod);
|
virtual void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod);
|
||||||
|
|
||||||
// Note: vector is passed by ref for performance. Don't reorder it.
|
// Note: vector is passed by ref for performance. Don't reorder it.
|
||||||
virtual void emerge_blocks(Vector<BlockRequest> &p_blocks);
|
virtual void emerge_blocks(Vector<VoxelBlockRequest> &p_blocks);
|
||||||
|
|
||||||
// Returns multiple blocks of voxels to the stream.
|
// Returns multiple blocks of voxels to the stream.
|
||||||
// Generators usually don't implement it.
|
// Generators usually don't implement it.
|
||||||
// This function is recommended if you save to files, because you can batch their access.
|
// This function is recommended if you save to files, because you can batch their access.
|
||||||
virtual void immerge_blocks(Vector<BlockRequest> &p_blocks);
|
virtual void immerge_blocks(Vector<VoxelBlockRequest> &p_blocks);
|
||||||
|
|
||||||
virtual bool is_thread_safe() const;
|
virtual bool is_thread_safe() const;
|
||||||
virtual bool is_cloneable() const;
|
virtual bool is_cloneable() const;
|
||||||
|
|
|
@ -23,18 +23,18 @@ void VoxelStreamFile::emerge_block_fallback(Ref<VoxelBuffer> out_buffer, Vector3
|
||||||
|
|
||||||
// This function is just a helper around the true thing, really. I might remove it in the future.
|
// This function is just a helper around the true thing, really. I might remove it in the future.
|
||||||
|
|
||||||
BlockRequest r;
|
VoxelBlockRequest r;
|
||||||
r.voxel_buffer = out_buffer;
|
r.voxel_buffer = out_buffer;
|
||||||
r.origin_in_voxels = origin_in_voxels;
|
r.origin_in_voxels = origin_in_voxels;
|
||||||
r.lod = lod;
|
r.lod = lod;
|
||||||
|
|
||||||
Vector<BlockRequest> requests;
|
Vector<VoxelBlockRequest> requests;
|
||||||
requests.push_back(r);
|
requests.push_back(r);
|
||||||
|
|
||||||
emerge_blocks_fallback(requests);
|
emerge_blocks_fallback(requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamFile::emerge_blocks_fallback(Vector<VoxelStreamFile::BlockRequest> &requests) {
|
void VoxelStreamFile::emerge_blocks_fallback(Vector<VoxelBlockRequest> &requests) {
|
||||||
VOXEL_PROFILE_SCOPE(profile_scope);
|
VOXEL_PROFILE_SCOPE(profile_scope);
|
||||||
|
|
||||||
if (_fallback_stream.is_valid()) {
|
if (_fallback_stream.is_valid()) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
void emerge_block_fallback(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod);
|
void emerge_block_fallback(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod);
|
||||||
void emerge_blocks_fallback(Vector<BlockRequest> &requests);
|
void emerge_blocks_fallback(Vector<VoxelBlockRequest> &requests);
|
||||||
|
|
||||||
FileAccess *open_file(const String &fpath, int mode_flags, Error *err);
|
FileAccess *open_file(const String &fpath, int mode_flags, Error *err);
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
#include "voxel_stream_heightmap.h"
|
|
||||||
#include "../util/array_slice.h"
|
|
||||||
#include "../util/fixed_array.h"
|
|
||||||
|
|
||||||
VoxelStreamHeightmap::VoxelStreamHeightmap() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamHeightmap::set_channel(VoxelBuffer::ChannelId channel) {
|
|
||||||
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
|
|
||||||
_channel = channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
VoxelBuffer::ChannelId VoxelStreamHeightmap::get_channel() const {
|
|
||||||
return _channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamHeightmap::set_height_start(float start) {
|
|
||||||
_range.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
float VoxelStreamHeightmap::get_height_start() const {
|
|
||||||
return _range.start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamHeightmap::set_height_range(float range) {
|
|
||||||
_range.height = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
float VoxelStreamHeightmap::get_height_range() const {
|
|
||||||
return _range.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamHeightmap::set_iso_scale(float iso_scale) {
|
|
||||||
_iso_scale = iso_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
float VoxelStreamHeightmap::get_iso_scale() const {
|
|
||||||
return _iso_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamHeightmap::_bind_methods() {
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelStreamHeightmap::set_channel);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelStreamHeightmap::get_channel);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_height_start", "start"), &VoxelStreamHeightmap::set_height_start);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_height_start"), &VoxelStreamHeightmap::get_height_start);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_height_range", "range"), &VoxelStreamHeightmap::set_height_range);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_height_range"), &VoxelStreamHeightmap::get_height_range);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_iso_scale", "scale"), &VoxelStreamHeightmap::set_iso_scale);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_iso_scale"), &VoxelStreamHeightmap::get_iso_scale);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel", PROPERTY_HINT_ENUM, VoxelBuffer::CHANNEL_ID_HINT_STRING), "set_channel", "get_channel");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_start"), "set_height_start", "get_height_start");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_range"), "set_height_range", "get_height_range");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "iso_scale"), "set_iso_scale", "get_iso_scale");
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
#include "voxel_stream_noise_2d.h"
|
|
||||||
|
|
||||||
VoxelStreamNoise2D::VoxelStreamNoise2D() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamNoise2D::set_noise(Ref<OpenSimplexNoise> noise) {
|
|
||||||
_noise = noise;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<OpenSimplexNoise> VoxelStreamNoise2D::get_noise() const {
|
|
||||||
return _noise;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamNoise2D::set_curve(Ref<Curve> curve) {
|
|
||||||
_curve = curve;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<Curve> VoxelStreamNoise2D::get_curve() const {
|
|
||||||
return _curve;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamNoise2D::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels, int lod) {
|
|
||||||
|
|
||||||
ERR_FAIL_COND(_noise.is_null());
|
|
||||||
|
|
||||||
VoxelBuffer &out_buffer = **p_out_buffer;
|
|
||||||
OpenSimplexNoise &noise = **_noise;
|
|
||||||
|
|
||||||
if (_curve.is_null()) {
|
|
||||||
VoxelStreamHeightmap::generate(out_buffer,
|
|
||||||
[&noise](int x, int z) { return 0.5 + 0.5 * noise.get_noise_2d(x, z); },
|
|
||||||
origin_in_voxels, lod);
|
|
||||||
} else {
|
|
||||||
Curve &curve = **_curve;
|
|
||||||
VoxelStreamHeightmap::generate(out_buffer,
|
|
||||||
[&noise, &curve](int x, int z) { return curve.interpolate_baked(0.5 + 0.5 * noise.get_noise_2d(x, z)); },
|
|
||||||
origin_in_voxels, lod);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_buffer.compress_uniform_channels();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelStreamNoise2D::_bind_methods() {
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &VoxelStreamNoise2D::set_noise);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_noise"), &VoxelStreamNoise2D::get_noise);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &VoxelStreamNoise2D::set_curve);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_curve"), &VoxelStreamNoise2D::get_curve);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
|
|
||||||
}
|
|
|
@ -27,42 +27,42 @@ VoxelStreamRegionFiles::~VoxelStreamRegionFiles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamRegionFiles::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {
|
void VoxelStreamRegionFiles::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {
|
||||||
BlockRequest r;
|
VoxelBlockRequest r;
|
||||||
r.voxel_buffer = out_buffer;
|
r.voxel_buffer = out_buffer;
|
||||||
r.origin_in_voxels = origin_in_voxels;
|
r.origin_in_voxels = origin_in_voxels;
|
||||||
r.lod = lod;
|
r.lod = lod;
|
||||||
Vector<BlockRequest> requests;
|
Vector<VoxelBlockRequest> requests;
|
||||||
requests.push_back(r);
|
requests.push_back(r);
|
||||||
emerge_blocks(requests);
|
emerge_blocks(requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamRegionFiles::immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod) {
|
void VoxelStreamRegionFiles::immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod) {
|
||||||
BlockRequest r;
|
VoxelBlockRequest r;
|
||||||
r.voxel_buffer = buffer;
|
r.voxel_buffer = buffer;
|
||||||
r.origin_in_voxels = origin_in_voxels;
|
r.origin_in_voxels = origin_in_voxels;
|
||||||
r.lod = lod;
|
r.lod = lod;
|
||||||
Vector<BlockRequest> requests;
|
Vector<VoxelBlockRequest> requests;
|
||||||
requests.push_back(r);
|
requests.push_back(r);
|
||||||
immerge_blocks(requests);
|
immerge_blocks(requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamRegionFiles::emerge_blocks(Vector<BlockRequest> &p_blocks) {
|
void VoxelStreamRegionFiles::emerge_blocks(Vector<VoxelBlockRequest> &p_blocks) {
|
||||||
VOXEL_PROFILE_SCOPE(profile_scope);
|
VOXEL_PROFILE_SCOPE(profile_scope);
|
||||||
|
|
||||||
// In order to minimize opening/closing files, requests are grouped according to their region.
|
// In order to minimize opening/closing files, requests are grouped according to their region.
|
||||||
|
|
||||||
// Had to copy input to sort it, as some areas in the module break if they get responses in different order
|
// Had to copy input to sort it, as some areas in the module break if they get responses in different order
|
||||||
Vector<BlockRequest> sorted_blocks;
|
Vector<VoxelBlockRequest> sorted_blocks;
|
||||||
sorted_blocks.append_array(p_blocks);
|
sorted_blocks.append_array(p_blocks);
|
||||||
|
|
||||||
SortArray<BlockRequest, BlockRequestComparator> sorter;
|
SortArray<VoxelBlockRequest, BlockRequestComparator> sorter;
|
||||||
sorter.compare.self = this;
|
sorter.compare.self = this;
|
||||||
sorter.sort(sorted_blocks.ptrw(), sorted_blocks.size());
|
sorter.sort(sorted_blocks.ptrw(), sorted_blocks.size());
|
||||||
|
|
||||||
Vector<BlockRequest> fallback_requests;
|
Vector<VoxelBlockRequest> fallback_requests;
|
||||||
|
|
||||||
for (int i = 0; i < sorted_blocks.size(); ++i) {
|
for (int i = 0; i < sorted_blocks.size(); ++i) {
|
||||||
BlockRequest &r = sorted_blocks.write[i];
|
VoxelBlockRequest &r = sorted_blocks.write[i];
|
||||||
EmergeResult result = _emerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
EmergeResult result = _emerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
||||||
if (result == EMERGE_OK_FALLBACK) {
|
if (result == EMERGE_OK_FALLBACK) {
|
||||||
fallback_requests.push_back(r);
|
fallback_requests.push_back(r);
|
||||||
|
@ -72,19 +72,19 @@ void VoxelStreamRegionFiles::emerge_blocks(Vector<BlockRequest> &p_blocks) {
|
||||||
emerge_blocks_fallback(fallback_requests);
|
emerge_blocks_fallback(fallback_requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStreamRegionFiles::immerge_blocks(Vector<BlockRequest> &p_blocks) {
|
void VoxelStreamRegionFiles::immerge_blocks(Vector<VoxelBlockRequest> &p_blocks) {
|
||||||
VOXEL_PROFILE_SCOPE(profile_scope);
|
VOXEL_PROFILE_SCOPE(profile_scope);
|
||||||
|
|
||||||
// Had to copy input to sort it, as some areas in the module break if they get responses in different order
|
// Had to copy input to sort it, as some areas in the module break if they get responses in different order
|
||||||
Vector<BlockRequest> sorted_blocks;
|
Vector<VoxelBlockRequest> sorted_blocks;
|
||||||
sorted_blocks.append_array(p_blocks);
|
sorted_blocks.append_array(p_blocks);
|
||||||
|
|
||||||
SortArray<BlockRequest, BlockRequestComparator> sorter;
|
SortArray<VoxelBlockRequest, BlockRequestComparator> sorter;
|
||||||
sorter.compare.self = this;
|
sorter.compare.self = this;
|
||||||
sorter.sort(sorted_blocks.ptrw(), sorted_blocks.size());
|
sorter.sort(sorted_blocks.ptrw(), sorted_blocks.size());
|
||||||
|
|
||||||
for (int i = 0; i < sorted_blocks.size(); ++i) {
|
for (int i = 0; i < sorted_blocks.size(); ++i) {
|
||||||
BlockRequest &r = sorted_blocks.write[i];
|
VoxelBlockRequest &r = sorted_blocks.write[i];
|
||||||
_immerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
_immerge_block(r.voxel_buffer, r.origin_in_voxels, r.lod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ public:
|
||||||
void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) override;
|
void emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||||
void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod) override;
|
void immerge_block(Ref<VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod) override;
|
||||||
|
|
||||||
void emerge_blocks(Vector<BlockRequest> &p_blocks) override;
|
void emerge_blocks(Vector<VoxelBlockRequest> &p_blocks) override;
|
||||||
void immerge_blocks(Vector<BlockRequest> &p_blocks) override;
|
void immerge_blocks(Vector<VoxelBlockRequest> &p_blocks) override;
|
||||||
|
|
||||||
String get_directory() const;
|
String get_directory() const;
|
||||||
void set_directory(String dirpath);
|
void set_directory(String dirpath);
|
||||||
|
@ -94,7 +94,7 @@ private:
|
||||||
VoxelStreamRegionFiles *self = nullptr;
|
VoxelStreamRegionFiles *self = nullptr;
|
||||||
|
|
||||||
// operator<
|
// operator<
|
||||||
_FORCE_INLINE_ bool operator()(const VoxelStreamRegionFiles::BlockRequest &a, const VoxelStreamRegionFiles::BlockRequest &b) const {
|
_FORCE_INLINE_ bool operator()(const VoxelBlockRequest &a, const VoxelBlockRequest &b) const {
|
||||||
if (a.lod < b.lod) {
|
if (a.lod < b.lod) {
|
||||||
return true;
|
return true;
|
||||||
} else if (a.lod > b.lod) {
|
} else if (a.lod > b.lod) {
|
||||||
|
|
|
@ -58,8 +58,8 @@ void VoxelDataLoader::process_blocks_thread_func(const ArraySlice<InputBlock> in
|
||||||
|
|
||||||
CRASH_COND(inputs.size() != outputs.size());
|
CRASH_COND(inputs.size() != outputs.size());
|
||||||
|
|
||||||
Vector<VoxelStream::BlockRequest> emerge_requests;
|
Vector<VoxelBlockRequest> emerge_requests;
|
||||||
Vector<VoxelStream::BlockRequest> immerge_requests;
|
Vector<VoxelBlockRequest> immerge_requests;
|
||||||
|
|
||||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ void VoxelDataLoader::process_blocks_thread_func(const ArraySlice<InputBlock> in
|
||||||
|
|
||||||
if (ib.data.voxels_to_save.is_null()) {
|
if (ib.data.voxels_to_save.is_null()) {
|
||||||
|
|
||||||
VoxelStream::BlockRequest r;
|
VoxelBlockRequest r;
|
||||||
r.voxel_buffer.instance();
|
r.voxel_buffer.instance();
|
||||||
r.voxel_buffer->create(bs, bs, bs);
|
r.voxel_buffer->create(bs, bs, bs);
|
||||||
r.origin_in_voxels = block_origin_in_voxels;
|
r.origin_in_voxels = block_origin_in_voxels;
|
||||||
|
@ -79,7 +79,7 @@ void VoxelDataLoader::process_blocks_thread_func(const ArraySlice<InputBlock> in
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
VoxelStream::BlockRequest r;
|
VoxelBlockRequest r;
|
||||||
r.voxel_buffer = ib.data.voxels_to_save;
|
r.voxel_buffer = ib.data.voxels_to_save;
|
||||||
r.origin_in_voxels = block_origin_in_voxels;
|
r.origin_in_voxels = block_origin_in_voxels;
|
||||||
r.lod = ib.lod;
|
r.lod = ib.lod;
|
||||||
|
|
|
@ -17,6 +17,7 @@ VoxelStringNames::VoxelStringNames() {
|
||||||
|
|
||||||
emerge_block = StaticCString::create("emerge_block");
|
emerge_block = StaticCString::create("emerge_block");
|
||||||
immerge_block = StaticCString::create("immerge_block");
|
immerge_block = StaticCString::create("immerge_block");
|
||||||
|
generate_block = StaticCString::create("generate_block");
|
||||||
|
|
||||||
u_transition_mask = StaticCString::create("u_transition_mask");
|
u_transition_mask = StaticCString::create("u_transition_mask");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
|
|
||||||
StringName emerge_block;
|
StringName emerge_block;
|
||||||
StringName immerge_block;
|
StringName immerge_block;
|
||||||
|
StringName generate_block;
|
||||||
|
|
||||||
StringName u_transition_mask;
|
StringName u_transition_mask;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue