98 lines
2.6 KiB
C++
98 lines
2.6 KiB
C++
#ifndef VOXEL_LIBRARY_H
|
|
#define VOXEL_LIBRARY_H
|
|
|
|
#include "../../util/dynamic_bitset.h"
|
|
#include "voxel.h"
|
|
#include <core/resource.h>
|
|
|
|
class VoxelLibrary : public Resource {
|
|
GDCLASS(VoxelLibrary, Resource)
|
|
|
|
public:
|
|
// Limit based on maximum supported by VoxelMesherBlocky
|
|
static const unsigned int MAX_VOXEL_TYPES = 65536;
|
|
static const uint32_t NULL_INDEX = 0xFFFFFFFF;
|
|
|
|
struct BakedData {
|
|
// 2D array: { X : pattern A, Y : pattern B } => Does A occlude B
|
|
// Where index is X + Y * pattern count
|
|
DynamicBitset side_pattern_culling;
|
|
unsigned int side_pattern_count = 0;
|
|
// Lots of data can get moved but it's only on load.
|
|
std::vector<Voxel::BakedData> models;
|
|
|
|
inline bool has_model(uint32_t i) const {
|
|
return i < models.size();
|
|
}
|
|
|
|
inline bool get_side_pattern_occlusion(unsigned int pattern_a, unsigned int pattern_b) const {
|
|
#ifdef DEBUG_ENABLED
|
|
CRASH_COND(pattern_a >= side_pattern_count);
|
|
CRASH_COND(pattern_b >= side_pattern_count);
|
|
#endif
|
|
return side_pattern_culling.get(pattern_a + pattern_b * side_pattern_count);
|
|
}
|
|
};
|
|
|
|
VoxelLibrary();
|
|
~VoxelLibrary();
|
|
|
|
int get_atlas_size() const { return _atlas_size; }
|
|
void set_atlas_size(int s);
|
|
|
|
// Use this factory rather than creating voxels from scratch
|
|
Ref<Voxel> create_voxel(unsigned int id, String name);
|
|
|
|
unsigned int get_voxel_count() const;
|
|
void set_voxel_count(unsigned int type_count);
|
|
|
|
bool get_bake_tangents() const { return _bake_tangents; }
|
|
void set_bake_tangents(bool bt);
|
|
|
|
void load_default();
|
|
|
|
int get_voxel_index_from_name(StringName name) const;
|
|
|
|
void bake();
|
|
|
|
//-------------------------
|
|
// Internal use
|
|
|
|
_FORCE_INLINE_ bool has_voxel(unsigned int id) const {
|
|
return id < _voxel_types.size() && _voxel_types[id].is_valid();
|
|
}
|
|
|
|
_FORCE_INLINE_ const Voxel &get_voxel_const(unsigned int id) const {
|
|
return **_voxel_types[id];
|
|
}
|
|
|
|
const BakedData &get_baked_data() const { return _baked_data; }
|
|
const RWLock &get_baked_data_rw_lock() const { return _baked_data_rw_lock; }
|
|
|
|
private:
|
|
void set_voxel(unsigned int id, Ref<Voxel> voxel);
|
|
|
|
void generate_side_culling_matrix();
|
|
|
|
bool _set(const StringName &p_name, const Variant &p_value);
|
|
bool _get(const StringName &p_name, Variant &r_ret) const;
|
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
|
|
|
Ref<Voxel> _b_get_voxel(unsigned int id);
|
|
Ref<Voxel> _b_get_voxel_by_name(StringName name);
|
|
|
|
static void _bind_methods();
|
|
|
|
private:
|
|
std::vector<Ref<Voxel> > _voxel_types;
|
|
int _atlas_size = 16;
|
|
bool _needs_baking = true;
|
|
bool _bake_tangents = true;
|
|
|
|
// Used in multithread context by the mesher. Don't modify that outside of bake().
|
|
RWLock _baked_data_rw_lock;
|
|
BakedData _baked_data;
|
|
};
|
|
|
|
#endif // VOXEL_LIBRARY_H
|