Split VoxelGeneratorTest into VoxelGeneratorWaves and VoxelGeneratorFlat

master
Marc Gilleron 2020-02-17 22:05:16 +00:00
parent b8ee140a89
commit c33f46a437
8 changed files with 228 additions and 217 deletions

View File

@ -0,0 +1,111 @@
#include "voxel_generator_flat.h"
VoxelGeneratorFlat::VoxelGeneratorFlat() {
}
void VoxelGeneratorFlat::set_channel(VoxelBuffer::ChannelId channel) {
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
if (_channel != channel) {
_channel = channel;
emit_changed();
}
}
VoxelBuffer::ChannelId VoxelGeneratorFlat::get_channel() const {
return _channel;
}
int VoxelGeneratorFlat::get_used_channels_mask() const {
return (1 << _channel);
}
void VoxelGeneratorFlat::set_voxel_type(int t) {
_voxel_type = t;
}
int VoxelGeneratorFlat::get_voxel_type() const {
return _voxel_type;
}
void VoxelGeneratorFlat::set_height(float h) {
_height = h;
}
void VoxelGeneratorFlat::generate_block(VoxelBlockRequest &input) {
ERR_FAIL_COND(input.voxel_buffer.is_null());
VoxelBuffer &out_buffer = **input.voxel_buffer;
const Vector3i origin = input.origin_in_voxels;
const int channel = _channel;
const Vector3i bs = out_buffer.get_size();
const bool use_sdf = channel == VoxelBuffer::CHANNEL_SDF;
const float margin = 1 << input.lod;
const int lod = input.lod;
if (origin.y > _height + margin) {
// The bottom of the block is above the highest ground can go (default is air)
return;
}
if (origin.y + (bs.y << lod) < _height - margin) {
// The top of the block is below the lowest ground can go
out_buffer.clear_channel(_channel, use_sdf ? 0 : _voxel_type);
return;
}
const int stride = 1 << lod;
if (use_sdf) {
int gz = origin.z;
for (int z = 0; z < bs.z; ++z, gz += stride) {
int gx = origin.x;
for (int x = 0; x < bs.x; ++x, gx += stride) {
int gy = origin.y;
for (int y = 0; y < bs.y; ++y, gy += stride) {
float sdf = _iso_scale * (gy - _height);
out_buffer.set_voxel_f(sdf, x, y, z, channel);
}
} // for x
} // for z
} else {
// Blocky
int gz = origin.z;
for (int z = 0; z < bs.z; ++z, gz += stride) {
int gx = origin.x;
for (int x = 0; x < bs.x; ++x, gx += stride) {
float h = _height - origin.y;
int ih = int(h);
if (ih > 0) {
if (ih > bs.y) {
ih = bs.y;
}
out_buffer.fill_area(_voxel_type, Vector3i(x, 0, z), Vector3i(x + 1, ih, z + 1), channel);
}
} // for x
} // for z
} // use_sdf
}
void VoxelGeneratorFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelGeneratorFlat::set_channel);
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelGeneratorFlat::get_channel);
ClassDB::bind_method(D_METHOD("set_voxel_type", "id"), &VoxelGeneratorFlat::set_voxel_type);
ClassDB::bind_method(D_METHOD("get_voxel_type"), &VoxelGeneratorFlat::get_voxel_type);
ClassDB::bind_method(D_METHOD("set_height", "h"), &VoxelGeneratorFlat::set_height);
ClassDB::bind_method(D_METHOD("get_height"), &VoxelGeneratorFlat::get_height);
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel", PROPERTY_HINT_ENUM, VoxelBuffer::CHANNEL_ID_HINT_STRING), "set_channel", "get_channel");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_type", PROPERTY_HINT_RANGE, "0,65536,1"), "set_voxel_type", "get_voxel_type");
}

View File

@ -0,0 +1,34 @@
#ifndef VOXEL_GENERATOR_FLAT_H
#define VOXEL_GENERATOR_FLAT_H
#include "voxel_generator.h"
class VoxelGeneratorFlat : public VoxelGenerator {
GDCLASS(VoxelGeneratorFlat, VoxelGenerator)
public:
VoxelGeneratorFlat();
void set_channel(VoxelBuffer::ChannelId channel);
VoxelBuffer::ChannelId get_channel() const;
int get_used_channels_mask() const override;
void generate_block(VoxelBlockRequest &input) override;
void set_voxel_type(int t);
int get_voxel_type() const;
void set_height(float h);
float get_height() const { return _height; }
protected:
static void _bind_methods();
private:
VoxelBuffer::ChannelId _channel = VoxelBuffer::CHANNEL_SDF;
int _voxel_type = 1;
float _height = 0;
float _iso_scale = 0.1;
};
#endif // VOXEL_GENERATOR_FLAT_H

View File

@ -7,7 +7,7 @@ VoxelGeneratorHeightmap::VoxelGeneratorHeightmap() {
void VoxelGeneratorHeightmap::set_channel(VoxelBuffer::ChannelId channel) {
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
if(_channel != channel) {
if (_channel != channel) {
_channel = channel;
emit_changed();
}
@ -18,7 +18,7 @@ VoxelBuffer::ChannelId VoxelGeneratorHeightmap::get_channel() const {
}
int VoxelGeneratorHeightmap::get_used_channels_mask() const {
return (1<<_channel);
return (1 << _channel);
}
void VoxelGeneratorHeightmap::set_height_start(float start) {
@ -59,6 +59,7 @@ void VoxelGeneratorHeightmap::_bind_methods() {
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");

View File

@ -1,157 +0,0 @@
#include "voxel_generator_test.h"
VARIANT_ENUM_CAST(VoxelGeneratorTest::Mode)
VoxelGeneratorTest::VoxelGeneratorTest() {
_mode = MODE_WAVES;
_voxel_type = 1;
_pattern_size = Vector3i(10, 10, 10);
}
void VoxelGeneratorTest::set_channel(VoxelBuffer::ChannelId channel) {
ERR_FAIL_INDEX(channel, VoxelBuffer::MAX_CHANNELS);
if(_channel != channel) {
_channel = channel;
emit_changed();
}
}
VoxelBuffer::ChannelId VoxelGeneratorTest::get_channel() const {
return _channel;
}
int VoxelGeneratorTest::get_used_channels_mask() const {
return (1<<_channel);
}
void VoxelGeneratorTest::set_mode(Mode mode) {
ERR_FAIL_INDEX(mode, MODE_COUNT);
_mode = mode;
}
void VoxelGeneratorTest::set_voxel_type(int t) {
_voxel_type = t;
}
int VoxelGeneratorTest::get_voxel_type() const {
return _voxel_type;
}
void VoxelGeneratorTest::set_pattern_size(Vector3i size) {
ERR_FAIL_COND(size.x < 1 || size.y < 1 || size.z < 1);
_pattern_size = size;
}
void VoxelGeneratorTest::set_pattern_offset(Vector3i offset) {
_pattern_offset = offset;
}
void VoxelGeneratorTest::generate_block(VoxelBlockRequest &input) {
ERR_FAIL_COND(input.voxel_buffer.is_null());
if (input.lod != 0) {
// TODO Handle higher lods
return;
}
switch (_mode) {
case MODE_FLAT:
generate_block_flat(**input.voxel_buffer, input.origin_in_voxels, input.lod);
break;
case MODE_WAVES:
generate_block_waves(**input.voxel_buffer, input.origin_in_voxels, input.lod);
break;
default:
CRASH_NOW_MSG("Mode is unrecognized.");
break;
}
}
void VoxelGeneratorTest::generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
// TODO Don't expect a block pos, but a voxel pos!
Vector3i size = out_buffer.get_size();
int rh = _pattern_offset.y - origin.y;
if (rh > size.y)
rh = size.y;
for (int rz = 0; rz < size.z; ++rz) {
for (int rx = 0; rx < size.x; ++rx) {
for (int ry = 0; ry < rh; ++ry) {
out_buffer.set_voxel(_voxel_type, rx, ry, rz, _channel);
}
}
}
}
void VoxelGeneratorTest::generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod) {
// TODO Don't expect a block pos, but a voxel pos!
Vector3i size = out_buffer.get_size();
//origin += _pattern_offset;
float amplitude = static_cast<float>(_pattern_size.y);
float period_x = 1.f / static_cast<float>(_pattern_size.x);
float period_z = 1.f / static_cast<float>(_pattern_size.z);
//out_buffer.fill(0, 1); // TRANSVOXEL TEST
if (origin.y + size.y < Math::floor(_pattern_offset.y - 1.5 * amplitude)) {
// Everything is ground
out_buffer.fill(_voxel_type);
} else if (origin.y > Math::ceil(_pattern_offset.y + 1.5 * amplitude)) {
// Everything is air
return;
} else {
for (int rz = 0; rz < size.z; ++rz) {
for (int rx = 0; rx < size.x; ++rx) {
float x = origin.x + rx;
float z = origin.z + rz;
int h = _pattern_offset.y + amplitude * (Math::cos(x * period_x) + Math::sin(z * period_z));
int rh = h - origin.y;
if (rh > size.y)
rh = size.y;
for (int ry = 0; ry < rh; ++ry) {
out_buffer.set_voxel(_voxel_type, rx, ry, rz, _channel);
//out_buffer.set_voxel(255, rx, ry, rz, 1); // TRANSVOXEL TEST
}
}
}
}
}
void VoxelGeneratorTest::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &VoxelGeneratorTest::set_channel);
ClassDB::bind_method(D_METHOD("get_channel"), &VoxelGeneratorTest::get_channel);
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VoxelGeneratorTest::set_mode);
ClassDB::bind_method(D_METHOD("get_mode"), &VoxelGeneratorTest::get_mode);
ClassDB::bind_method(D_METHOD("set_voxel_type", "id"), &VoxelGeneratorTest::set_voxel_type);
ClassDB::bind_method(D_METHOD("get_voxel_type"), &VoxelGeneratorTest::get_voxel_type);
ClassDB::bind_method(D_METHOD("set_pattern_size", "size"), &VoxelGeneratorTest::_set_pattern_size);
ClassDB::bind_method(D_METHOD("get_pattern_size"), &VoxelGeneratorTest::_get_pattern_size);
ClassDB::bind_method(D_METHOD("set_pattern_offset", "offset"), &VoxelGeneratorTest::_set_pattern_offset);
ClassDB::bind_method(D_METHOD("get_pattern_offset"), &VoxelGeneratorTest::_get_pattern_offset);
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel", PROPERTY_HINT_ENUM, VoxelBuffer::CHANNEL_ID_HINT_STRING), "set_channel", "get_channel");
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::VECTOR3, "pattern_size"), "set_pattern_size", "get_pattern_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "pattern_offset"), "set_pattern_offset", "get_pattern_offset");
BIND_ENUM_CONSTANT(MODE_FLAT);
BIND_ENUM_CONSTANT(MODE_WAVES);
}

View File

@ -1,56 +0,0 @@
#ifndef VOXEL_GENERATOR_TEST_H
#define VOXEL_GENERATOR_TEST_H
#include "voxel_generator.h"
class VoxelGeneratorTest : public VoxelGenerator {
GDCLASS(VoxelGeneratorTest, VoxelGenerator)
public:
enum Mode {
MODE_FLAT,
MODE_WAVES,
MODE_COUNT
};
VoxelGeneratorTest();
void set_channel(VoxelBuffer::ChannelId channel);
VoxelBuffer::ChannelId get_channel() const;
int get_used_channels_mask() const override;
void generate_block(VoxelBlockRequest &input) override;
void set_mode(Mode mode);
Mode get_mode() const { return _mode; }
void set_voxel_type(int t);
int get_voxel_type() const;
Vector3i get_pattern_size() const { return _pattern_size; }
void set_pattern_size(Vector3i size);
Vector3i get_pattern_offset() const { return _pattern_offset; }
void set_pattern_offset(Vector3i offset);
protected:
void generate_block_flat(VoxelBuffer &out_buffer, Vector3i origin, int lod);
void generate_block_waves(VoxelBuffer &out_buffer, Vector3i origin, int lod);
static void _bind_methods();
Vector3 _get_pattern_size() const { return get_pattern_size().to_vec3(); }
void _set_pattern_size(Vector3 size) { set_pattern_size(Vector3i(size)); }
Vector3 _get_pattern_offset() const { return get_pattern_offset().to_vec3(); }
void _set_pattern_offset(Vector3 offset) { set_pattern_offset(Vector3i(offset)); }
private:
VoxelBuffer::ChannelId _channel = VoxelBuffer::CHANNEL_SDF;
Mode _mode;
int _voxel_type;
Vector3i _pattern_offset;
Vector3i _pattern_size;
};
#endif // VOXEL_GENERATOR_TEST_H

View File

@ -0,0 +1,46 @@
#include "voxel_generator_waves.h"
#include "../util/utility.h"
#include <cmath>
VoxelGeneratorWaves::VoxelGeneratorWaves() {
_pattern_size = Vector2(30, 30);
set_height_range(30);
}
void VoxelGeneratorWaves::generate_block(VoxelBlockRequest &input) {
VoxelBuffer &out_buffer = **input.voxel_buffer;
const Vector2 freq(
Math_PI / static_cast<float>(_pattern_size.x),
Math_PI / static_cast<float>(_pattern_size.y));
const Vector2 offset = _pattern_offset;
VoxelGeneratorHeightmap::generate(out_buffer,
[freq, offset](int x, int z) {
return 0.5 + 0.25 * (Math::cos((x + offset.x) * freq.x) + Math::sin((z + offset.y) * freq.y));
},
input.origin_in_voxels, input.lod);
}
void VoxelGeneratorWaves::set_pattern_size(Vector2 size) {
size.x = max(size.x, 0.1f);
size.y = max(size.y, 0.1f);
_pattern_size = size;
}
void VoxelGeneratorWaves::set_pattern_offset(Vector2 offset) {
_pattern_offset = offset;
}
void VoxelGeneratorWaves::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pattern_size", "size"), &VoxelGeneratorWaves::set_pattern_size);
ClassDB::bind_method(D_METHOD("get_pattern_size"), &VoxelGeneratorWaves::get_pattern_size);
ClassDB::bind_method(D_METHOD("set_pattern_offset", "offset"), &VoxelGeneratorWaves::set_pattern_offset);
ClassDB::bind_method(D_METHOD("get_pattern_offset"), &VoxelGeneratorWaves::get_pattern_offset);
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel", PROPERTY_HINT_ENUM, VoxelBuffer::CHANNEL_ID_HINT_STRING), "set_channel", "get_channel");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pattern_size"), "set_pattern_size", "get_pattern_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pattern_offset"), "set_pattern_offset", "get_pattern_offset");
}

View File

@ -0,0 +1,30 @@
#ifndef VOXEL_GENERATOR_WAVES_H
#define VOXEL_GENERATOR_WAVES_H
#include "voxel_generator_heightmap.h"
class VoxelGeneratorWaves : public VoxelGeneratorHeightmap {
GDCLASS(VoxelGeneratorWaves, VoxelGeneratorHeightmap)
public:
VoxelGeneratorWaves();
void set_channel(VoxelBuffer::ChannelId channel);
VoxelBuffer::ChannelId get_channel() const;
void generate_block(VoxelBlockRequest &input) override;
Vector2 get_pattern_size() const { return _pattern_size; }
void set_pattern_size(Vector2 size);
Vector2 get_pattern_offset() const { return _pattern_offset; }
void set_pattern_offset(Vector2 offset);
private:
static void _bind_methods();
Vector2 _pattern_size;
Vector2 _pattern_offset;
};
#endif // VOXEL_GENERATOR_WAVES_H

View File

@ -1,10 +1,11 @@
#include "register_types.h"
#include "edition/voxel_tool.h"
#include "generators/voxel_generator_flat.h"
#include "generators/voxel_generator_heightmap.h"
#include "generators/voxel_generator_image.h"
#include "generators/voxel_generator_noise.h"
#include "generators/voxel_generator_noise_2d.h"
#include "generators/voxel_generator_test.h"
#include "generators/voxel_generator_waves.h"
#include "meshers/blocky/voxel_library.h"
#include "meshers/blocky/voxel_mesher_blocky.h"
#include "meshers/dmc/voxel_mesher_dmc.h"
@ -42,7 +43,8 @@ void register_voxel_types() {
// Generators
ClassDB::register_class<VoxelGenerator>();
ClassDB::register_class<VoxelGeneratorTest>();
ClassDB::register_class<VoxelGeneratorFlat>();
ClassDB::register_class<VoxelGeneratorWaves>();
ClassDB::register_class<VoxelGeneratorHeightmap>();
ClassDB::register_class<VoxelGeneratorImage>();
ClassDB::register_class<VoxelGeneratorNoise2D>();