2019-05-25 08:07:38 -07:00
|
|
|
#ifndef VOXEL_STREAM_H
|
|
|
|
#define VOXEL_STREAM_H
|
2017-01-01 17:15:57 -08:00
|
|
|
|
2022-04-10 12:10:33 -07:00
|
|
|
#include "../util/memory.h"
|
2022-04-18 16:32:37 -07:00
|
|
|
#include "../util/thread/rw_lock.h"
|
2021-02-07 09:22:50 -08:00
|
|
|
#include "instance_data.h"
|
2022-04-18 16:32:37 -07:00
|
|
|
|
2021-12-13 13:38:10 -08:00
|
|
|
#include <core/io/resource.h>
|
2017-01-01 17:15:57 -08:00
|
|
|
|
2022-01-09 14:13:10 -08:00
|
|
|
namespace zylann::voxel {
|
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
class VoxelBufferInternal;
|
2022-02-02 16:02:10 -08:00
|
|
|
|
2022-02-15 13:49:20 -08:00
|
|
|
namespace gd {
|
|
|
|
class VoxelBuffer;
|
|
|
|
}
|
|
|
|
|
2020-01-26 14:34:26 -08:00
|
|
|
// Provides access to a source of paged voxel data, which may load and save.
|
2021-01-17 09:18:05 -08:00
|
|
|
// This is intented for files, so it may run in a single background thread and gets requests in batches.
|
|
|
|
// Must be implemented in a thread-safe way.
|
|
|
|
//
|
2021-01-28 14:02:49 -08:00
|
|
|
// Functions currently don't enforce querying blocks of the same size, however it is required for every stream to
|
|
|
|
// support querying blocks the size of the declared block size, at positions matching their origins.
|
|
|
|
// This might be restricted in the future, because there has been no compelling use case for that.
|
|
|
|
//
|
2021-01-17 09:18:05 -08:00
|
|
|
// If you are looking for a more specialized API to generate voxels with more threads, use VoxelGenerator.
|
|
|
|
//
|
2019-05-25 08:07:38 -07:00
|
|
|
class VoxelStream : public Resource {
|
|
|
|
GDCLASS(VoxelStream, Resource)
|
2017-01-01 17:15:57 -08:00
|
|
|
public:
|
2019-08-18 15:13:12 -07:00
|
|
|
VoxelStream();
|
2021-01-17 09:18:05 -08:00
|
|
|
~VoxelStream();
|
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
enum ResultCode {
|
2021-01-17 09:18:05 -08:00
|
|
|
// Something went wrong, the request should be aborted
|
|
|
|
RESULT_ERROR,
|
|
|
|
// The block could not be found in the stream. The requester may fallback on the generator.
|
|
|
|
RESULT_BLOCK_NOT_FOUND,
|
|
|
|
// The block was found, so the requester won't use the generator.
|
|
|
|
RESULT_BLOCK_FOUND,
|
|
|
|
|
|
|
|
_RESULT_COUNT
|
|
|
|
};
|
2019-08-18 15:13:12 -07:00
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
struct VoxelQueryData {
|
|
|
|
VoxelBufferInternal &voxel_buffer;
|
|
|
|
Vector3i origin_in_voxels;
|
|
|
|
int lod;
|
|
|
|
// This is currently not used in save queries. Maybe it should?
|
|
|
|
ResultCode result;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct InstancesQueryData {
|
2022-04-10 12:10:33 -07:00
|
|
|
UniquePtr<InstanceBlockData> data;
|
2022-02-12 15:37:02 -08:00
|
|
|
Vector3i position;
|
|
|
|
uint8_t lod;
|
|
|
|
ResultCode result;
|
|
|
|
};
|
|
|
|
|
2021-02-07 09:22:50 -08:00
|
|
|
// TODO Deprecate
|
2020-01-21 12:00:29 -08:00
|
|
|
// Queries a block of voxels beginning at the given world-space voxel position and LOD.
|
|
|
|
// If you use LOD, the result at a given coordinate must always remain the same regardless of it.
|
|
|
|
// In other words, voxels values must solely depend on their coordinates or fixed parameters.
|
2022-02-12 15:37:02 -08:00
|
|
|
virtual void load_voxel_block(VoxelQueryData &query_data);
|
2020-01-21 12:00:29 -08:00
|
|
|
|
2021-02-07 09:22:50 -08:00
|
|
|
// TODO Deprecate
|
2022-02-12 15:37:02 -08:00
|
|
|
virtual void save_voxel_block(VoxelQueryData &query_data);
|
2017-01-01 17:15:57 -08:00
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
// Note: Don't modify the order of `p_blocks`.
|
2022-02-12 15:37:02 -08:00
|
|
|
virtual void load_voxel_blocks(Span<VoxelQueryData> p_blocks);
|
2020-01-21 12:00:29 -08:00
|
|
|
|
|
|
|
// Returns multiple blocks of voxels to the stream.
|
|
|
|
// This function is recommended if you save to files, because you can batch their access.
|
2022-02-12 15:37:02 -08:00
|
|
|
virtual void save_voxel_blocks(Span<VoxelQueryData> p_blocks);
|
2019-08-14 12:34:06 -07:00
|
|
|
|
2021-10-02 17:48:07 -07:00
|
|
|
// TODO Merge support functions into a single getter with Feature bitmask
|
2021-02-07 09:22:50 -08:00
|
|
|
virtual bool supports_instance_blocks() const;
|
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
virtual void load_instance_blocks(Span<InstancesQueryData> out_blocks);
|
|
|
|
virtual void save_instance_blocks(Span<InstancesQueryData> p_blocks);
|
2021-02-07 09:22:50 -08:00
|
|
|
|
2021-10-02 17:48:07 -07:00
|
|
|
struct FullLoadingResult {
|
|
|
|
struct Block {
|
2022-01-09 14:13:10 -08:00
|
|
|
std::shared_ptr<VoxelBufferInternal> voxels;
|
2022-04-10 12:10:33 -07:00
|
|
|
UniquePtr<InstanceBlockData> instances_data;
|
2021-10-02 17:48:07 -07:00
|
|
|
Vector3i position;
|
|
|
|
unsigned int lod;
|
|
|
|
};
|
|
|
|
std::vector<Block> blocks;
|
|
|
|
};
|
|
|
|
|
2022-01-04 14:15:57 -08:00
|
|
|
virtual bool supports_loading_all_blocks() const {
|
|
|
|
return false;
|
|
|
|
}
|
2021-10-02 17:48:07 -07:00
|
|
|
|
|
|
|
virtual void load_all_blocks(FullLoadingResult &result);
|
|
|
|
|
2021-01-28 14:02:49 -08:00
|
|
|
// Tells which channels can be found in this stream.
|
|
|
|
// The simplest implementation is to return them all.
|
|
|
|
// One reason to specify which channels are available is to help the editor detect configuration issues,
|
|
|
|
// and to avoid saving some of the channels if only specific ones are meant to be saved.
|
2020-02-14 11:12:13 -08:00
|
|
|
virtual int get_used_channels_mask() const;
|
|
|
|
|
2021-01-17 09:18:05 -08:00
|
|
|
// Gets which block size this stream will provide, as a power of two.
|
|
|
|
// File streams are likely to impose a specific block size,
|
|
|
|
// and changing it can be very expensive so the API is usually specific too
|
|
|
|
virtual int get_block_size_po2() const;
|
|
|
|
|
|
|
|
// Gets at how many levels of details blocks can be queried.
|
|
|
|
virtual int get_lod_count() const;
|
|
|
|
|
|
|
|
// Should generated blocks be saved immediately? If not, they will be saved only when modified.
|
|
|
|
void set_save_generator_output(bool enabled);
|
|
|
|
bool get_save_generator_output() const;
|
2020-08-14 12:33:09 -07:00
|
|
|
|
2021-01-17 09:18:05 -08:00
|
|
|
private:
|
2017-01-01 17:15:57 -08:00
|
|
|
static void _bind_methods();
|
|
|
|
|
2022-02-15 13:49:20 -08:00
|
|
|
ResultCode _b_load_voxel_block(Ref<gd::VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod);
|
|
|
|
void _b_save_voxel_block(Ref<gd::VoxelBuffer> buffer, Vector3i origin_in_voxels, int lod);
|
2021-01-17 09:18:05 -08:00
|
|
|
int _b_get_used_channels_mask() const;
|
|
|
|
Vector3 _b_get_block_size() const;
|
2022-01-15 20:21:02 -08:00
|
|
|
// Deprecated
|
2022-02-15 13:49:20 -08:00
|
|
|
ResultCode _b_emerge_block(Ref<gd::VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod);
|
|
|
|
void _b_immerge_block(Ref<gd::VoxelBuffer> buffer, Vector3 origin_in_voxels, int lod);
|
2021-01-17 09:18:05 -08:00
|
|
|
|
|
|
|
struct Parameters {
|
2021-01-21 11:40:26 -08:00
|
|
|
bool save_generator_output = false;
|
2021-01-17 09:18:05 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
Parameters _parameters;
|
2021-02-18 17:30:22 -08:00
|
|
|
RWLock _parameters_lock;
|
2017-01-01 17:15:57 -08:00
|
|
|
};
|
|
|
|
|
2022-01-09 14:13:10 -08:00
|
|
|
} // namespace zylann::voxel
|
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
VARIANT_ENUM_CAST(zylann::voxel::VoxelStream::ResultCode);
|
2021-01-17 09:18:05 -08:00
|
|
|
|
2019-05-25 08:16:03 -07:00
|
|
|
#endif // VOXEL_STREAM_H
|