Files
academy2/modules/world/world_generator.h
2021-10-14 13:42:21 +03:00

70 lines
1.6 KiB
C++

#ifndef VOXEL_GENERATOR_NOISE_2D_H
#define VOXEL_GENERATOR_NOISE_2D_H
#include <modules/voxel/generators/voxel_generator.h>
class WorldGenerator : public VoxelGenerator {
GDCLASS(WorldGenerator, VoxelGenerator)
public:
WorldGenerator();
int get_used_channels_mask() const override;
void set_iso_scale(float iso_scale);
float get_iso_scale() const;
Result generate_block(VoxelBlockRequest &input) override;
float height_func(int x, int y, int z);
private:
static void _bind_methods();
protected:
template <typename Height_F>
Result generate(VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
const int channel = VoxelBuffer::CHANNEL_SDF;
const Vector3i bs = out_buffer.get_size();
/* TODO: get via RoadsData */
if (origin.y > 300.0f) {
// The bottom of the block is above the highest ground can go (default is air)
Result result;
result.max_lod_hint = true;
return result;
}
if (origin.y + (bs.y << lod) < -1000.0f) {
// The top of the block is below the lowest ground can go
out_buffer.clear_channel(channel, 0);
Result result;
result.max_lod_hint = true;
return result;
}
const int stride = 1 << lod;
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 = height_func(gx, gy, gz);
out_buffer.set_voxel_f(sdf * _iso_scale, x, y, z, channel);
}
} // for x
} // for z
return Result();
}
private:
int _matter_type = 1;
float _iso_scale = 0.1;
};
#endif // VOXEL_GENERATOR_NOISE_2D_H