Ported the Material Cache and the VoxelLibraryMergerPCM classes from Terraman.

This commit is contained in:
Relintai 2022-02-08 22:47:06 +01:00
parent fe4a83b909
commit 3410575387
18 changed files with 2108 additions and 5 deletions

3
SCsub
View File

@ -32,6 +32,7 @@ sources = [
"library/voxel_surface.cpp",
"library/voxel_surface_simple.cpp",
"library/voxel_material_cache.cpp",
"data/voxel_light.cpp",
@ -84,6 +85,8 @@ sources = [
if has_texture_packer:
sources.append("library/voxel_library_merger.cpp")
sources.append("library/voxel_surface_merger.cpp")
sources.append("library/voxel_library_merger_pcm.cpp")
sources.append("library/voxel_material_cache_pcm.cpp")
if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes':
# Shared lib compilation

View File

@ -24,6 +24,10 @@ def get_doc_classes():
"VoxelLibraryMerger",
"VoxelLibrarySimple",
"VoxelLibrary",
"VoxelLibraryMergerPCM",
"VoxelMaterialCache",
"VoxelMaterialCachePCM",
"VoxelCubePoints",
"VoxelMesherCubic",

View File

@ -702,16 +702,28 @@
</member>
<member name="library" type="VoxelLibrary" setter="set_library" getter="get_library">
</member>
<member name="liquid_material_cache_key" type="int" setter="liquid_material_cache_key_set" getter="liquid_material_cache_key_get" default="0">
</member>
<member name="liquid_material_cache_key_has" type="bool" setter="liquid_material_cache_key_has_set" getter="liquid_material_cache_key_has" default="false">
</member>
<member name="margin_end" type="int" setter="set_margin_end" getter="get_margin_end" default="0">
</member>
<member name="margin_start" type="int" setter="set_margin_start" getter="get_margin_start" default="0">
</member>
<member name="material_cache_key" type="int" setter="material_cache_key_set" getter="material_cache_key_get" default="0">
</member>
<member name="material_cache_key_has" type="bool" setter="material_cache_key_has_set" getter="material_cache_key_has" default="false">
</member>
<member name="position_x" type="int" setter="set_position_x" getter="get_position_x" default="0">
</member>
<member name="position_y" type="int" setter="set_position_y" getter="get_position_y" default="0">
</member>
<member name="position_z" type="int" setter="set_position_z" getter="get_position_z" default="0">
</member>
<member name="prop_material_cache_key" type="int" setter="prop_material_cache_key_set" getter="prop_material_cache_key_get" default="0">
</member>
<member name="prop_material_cache_key_has" type="bool" setter="prop_material_cache_key_has_set" getter="prop_material_cache_key_has" default="false">
</member>
<member name="size_x" type="int" setter="set_size_x" getter="get_size_x" default="0">
</member>
<member name="size_y" type="int" setter="set_size_y" getter="get_size_y" default="0">

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VoxelLibraryMergerPCM" inherits="VoxelLibrary" version="3.5">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_prop_packer">
<return type="TexturePacker" />
<description>
</description>
</method>
<method name="get_prop_uv_rect">
<return type="Rect2" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
</methods>
<members>
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color( 0, 0, 0, 1 )">
</member>
<member name="keep_original_atlases" type="bool" setter="set_keep_original_atlases" getter="get_keep_original_atlases" default="false">
</member>
<member name="margin" type="int" setter="set_margin" getter="get_margin" default="0">
</member>
<member name="max_atlas_size" type="int" setter="set_max_atlas_size" getter="get_max_atlas_size" default="1024">
</member>
<member name="props" type="Array" setter="set_props" getter="get_props" default="[ ]">
</member>
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="5">
</member>
<member name="voxel_surfaces" type="Array" setter="set_voxel_surfaces" getter="get_voxel_surfaces" default="[ ]">
</member>
</members>
<constants>
</constants>
</class>

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VoxelMaterialCache" inherits="Resource" version="3.5">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="_setup_material_albedo" qualifiers="virtual">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
<method name="additional_texture_add">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
<method name="additional_texture_count">
<return type="int" />
<description>
</description>
</method>
<method name="additional_texture_get">
<return type="Texture" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="additional_texture_get_atlas">
<return type="AtlasTexture" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="additional_texture_get_atlas_tex">
<return type="AtlasTexture" />
<argument index="0" name="index" type="Texture" />
<description>
</description>
</method>
<method name="additional_texture_get_uv_rect">
<return type="Rect2" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
<method name="additional_texture_remove">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
<method name="additional_texture_remove_index">
<return type="void" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="additional_textures_clear">
<return type="void" />
<description>
</description>
</method>
<method name="dec_ref_count">
<return type="void" />
<description>
</description>
</method>
<method name="inc_ref_count">
<return type="void" />
<description>
</description>
</method>
<method name="material_add">
<return type="void" />
<argument index="0" name="value" type="Material" />
<description>
</description>
</method>
<method name="material_get">
<return type="Material" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="material_get_num" qualifiers="const">
<return type="int" />
<description>
</description>
</method>
<method name="material_lod_get">
<return type="Material" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="material_remove">
<return type="void" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="material_set">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="value" type="Material" />
<description>
</description>
</method>
<method name="materials_clear">
<return type="void" />
<description>
</description>
</method>
<method name="prop_add_textures">
<return type="void" />
<argument index="0" name="prop" type="PropData" />
<description>
</description>
</method>
<method name="prop_remove_textures">
<return type="void" />
<argument index="0" name="prop" type="PropData" />
<description>
</description>
</method>
<method name="refresh_rects">
<return type="void" />
<description>
</description>
</method>
<method name="setup_material_albedo">
<return type="void" />
<argument index="0" name="texture" type="Texture" />
<description>
</description>
</method>
<method name="surface_add">
<return type="void" />
<argument index="0" name="value" type="VoxelSurface" />
<description>
</description>
</method>
<method name="surface_get">
<return type="VoxelSurface" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="surface_get_num" qualifiers="const">
<return type="int" />
<description>
</description>
</method>
<method name="surface_id_get">
<return type="VoxelSurface" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="surface_remove">
<return type="void" />
<argument index="0" name="index" type="int" />
<description>
</description>
</method>
<method name="surface_set">
<return type="void" />
<argument index="0" name="index" type="int" />
<argument index="1" name="surface" type="VoxelSurface" />
<description>
</description>
</method>
<method name="surfaces_clear">
<return type="void" />
<description>
</description>
</method>
</methods>
<members>
<member name="initialized" type="bool" setter="set_initialized" getter="get_initialized" default="false">
</member>
<member name="mat_ref_count" type="int" setter="set_ref_count" getter="get_ref_count" default="0">
</member>
<member name="materials" type="Array" setter="materials_set" getter="materials_get" default="[ ]">
</member>
</members>
<constants>
</constants>
</class>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VoxelMaterialCachePCM" inherits="VoxelMaterialCache" version="3.5">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="background_color" type="Color" setter="set_background_color" getter="get_background_color" default="Color( 0, 0, 0, 1 )">
</member>
<member name="keep_original_atlases" type="bool" setter="set_keep_original_atlases" getter="get_keep_original_atlases" default="false">
</member>
<member name="margin" type="int" setter="set_margin" getter="get_margin" default="0">
</member>
<member name="max_atlas_size" type="int" setter="set_max_atlas_size" getter="get_max_atlas_size" default="1024">
</member>
<member name="texture_flags" type="int" setter="set_texture_flags" getter="get_texture_flags" default="5">
</member>
</members>
<constants>
</constants>
</class>

View File

@ -135,7 +135,6 @@ public:
protected:
static void _bind_methods();
private:
bool _initialized;
Vector<Ref<Material> > _materials;
Vector<Ref<Material> > _liquid_materials;

View File

@ -104,7 +104,6 @@ protected:
static void _bind_methods();
private:
Vector<Ref<VoxelSurfaceMerger> > _voxel_surfaces;
#ifdef PROPS_PRESENT
Vector<Ref<PropData> > _props;

View File

@ -0,0 +1,813 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "voxel_library_merger_pcm.h"
#include "../../texture_packer/texture_packer.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/texture.h"
#ifdef PROPS_PRESENT
#include "../../props/props/prop_data.h"
#include "../../props/props/prop_data_prop.h"
#if MESH_DATA_RESOURCE_PRESENT
#include "../../mesh_data_resource/props/prop_data_mesh_data.h"
#endif
#endif
#include "voxel_material_cache_pcm.h"
#include "../defines.h"
#include "../world/default/voxel_chunk_default.h"
#include "core/hashfuncs.h"
bool VoxelLibraryMergerPCM::_supports_caching() {
return true;
}
void VoxelLibraryMergerPCM::_material_cache_get_key(Ref<VoxelChunk> chunk) {
uint8_t *ch = chunk->channel_get(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
if (!ch) {
chunk->material_cache_key_set(0);
chunk->material_cache_key_has_set(false);
return;
}
Vector<uint8_t> surfaces;
uint32_t size = chunk->get_data_size();
for (uint32_t i = 0; i < size; ++i) {
uint8_t v = ch[i];
if (v == 0) {
continue;
}
int ssize = surfaces.size();
bool found = false;
for (uint8_t j = 0; j < ssize; ++j) {
if (surfaces[j] == v) {
found = true;
break;
}
}
if (!found) {
surfaces.push_back(v);
}
}
if (surfaces.size() == 0) {
chunk->material_cache_key_set(0);
chunk->material_cache_key_has_set(false);
return;
}
surfaces.sort();
String hstr;
for (int i = 0; i < surfaces.size(); ++i) {
hstr += String::num(surfaces[i]) + "|";
}
int hash = static_cast<int>(hstr.hash());
chunk->material_cache_key_set(hash);
chunk->material_cache_key_has_set(true);
_material_cache_mutex.lock();
if (_material_cache.has(hash)) {
Ref<VoxelMaterialCachePCM> cc = _material_cache[hash];
if (cc.is_valid()) {
cc->inc_ref_count();
}
_material_cache_mutex.unlock();
return;
}
//print_error("New cache: " + hstr);
Ref<VoxelMaterialCachePCM> cache;
cache.instance();
cache->inc_ref_count();
cache->set_texture_flags(get_texture_flags());
cache->set_max_atlas_size(get_max_atlas_size());
cache->set_keep_original_atlases(get_keep_original_atlases());
cache->set_background_color(get_background_color());
cache->set_margin(get_margin());
for (int i = 0; i < surfaces.size(); ++i) {
int s = surfaces[i] - 1;
if (_voxel_surfaces.size() <= s) {
continue;
}
Ref<VoxelSurfaceMerger> ms = _voxel_surfaces[s];
if (!ms.is_valid()) {
continue;
}
Ref<VoxelSurfaceMerger> nms = ms->duplicate();
nms->set_library(Ref<VoxelLibraryMergerPCM>(this));
nms->set_id(s);
cache->surface_add(nms);
}
for (int i = 0; i < _materials.size(); ++i) {
Ref<Material> m = _materials[i];
if (!m.is_valid()) {
continue;
}
Ref<Material> nm = m->duplicate();
cache->material_add(nm);
}
_material_cache[hash] = cache;
//unlock here, so if a different thread need the cache it will be able to immediately access the materials and surfaces when it gets it.
_material_cache_mutex.unlock();
//this will generate the atlases
cache->refresh_rects();
}
Ref<VoxelMaterialCache> VoxelLibraryMergerPCM::_material_cache_get(const int key) {
_material_cache_mutex.lock();
ERR_FAIL_COND_V(!_material_cache.has(key), Ref<VoxelMaterialCache>());
Ref<VoxelMaterialCache> c = _material_cache[key];
_material_cache_mutex.unlock();
return c;
}
void VoxelLibraryMergerPCM::_material_cache_unref(const int key) {
_material_cache_mutex.lock();
if (!_material_cache.has(key)) {
return;
}
Ref<VoxelMaterialCachePCM> cc = _material_cache[key];
if (!cc.is_valid()) {
return;
}
cc->dec_ref_count();
if (cc->get_ref_count() <= 0) {
_material_cache.erase(key);
}
_material_cache_mutex.unlock();
}
void VoxelLibraryMergerPCM::_prop_material_cache_get_key(Ref<VoxelChunk> chunk) {
Vector<uint64_t> props;
/*
#ifdef PROPS_PRESENT
for (int i = 0; i < chunk->prop_get_count(); ++i) {
Ref<PropData> prop = chunk->prop_get(i);
ERR_CONTINUE(!prop.is_valid());
//get pointer's value as uint64
uint64_t v = make_uint64_t<PropData *>(*prop);
int psize = props.size();
bool found = false;
for (int j = 0; j < psize; ++j) {
if (props[j] == v) {
found = true;
break;
}
}
if (!found) {
props.push_back(v);
}
}
#endif
*/
#if MESH_DATA_RESOURCE_PRESENT
for (int i = 0; i < chunk->mesh_data_resource_get_count(); ++i) {
Ref<Texture> tex = chunk->mesh_data_resource_get_texture(i);
if (!tex.is_valid())
continue;
//get pointer's value as uint64
uint64_t v = make_uint64_t<Texture *>(*tex);
int psize = props.size();
bool found = false;
for (int j = 0; j < psize; ++j) {
if (props[j] == v) {
found = true;
break;
}
}
if (!found) {
props.push_back(v);
}
}
#endif
if (props.size() == 0) {
chunk->prop_material_cache_key_set(0);
chunk->prop_material_cache_key_has_set(false);
return;
}
props.sort();
String hstr;
for (int i = 0; i < props.size(); ++i) {
hstr += String::num_uint64(props[i]) + "|";
}
int hash = static_cast<int>(hstr.hash());
chunk->prop_material_cache_key_set(hash);
chunk->prop_material_cache_key_has_set(true);
_prop_material_cache_mutex.lock();
if (_prop_material_cache.has(hash)) {
Ref<VoxelMaterialCachePCM> cc = _prop_material_cache[hash];
if (cc.is_valid()) {
cc->inc_ref_count();
}
_prop_material_cache_mutex.unlock();
return;
}
//print_error("New prop cache: " + hstr);
Ref<VoxelMaterialCachePCM> cache;
cache.instance();
cache->inc_ref_count();
cache->set_texture_flags(get_texture_flags());
cache->set_max_atlas_size(get_max_atlas_size());
cache->set_keep_original_atlases(get_keep_original_atlases());
cache->set_background_color(get_background_color());
cache->set_margin(get_margin());
for (int i = 0; i < _prop_materials.size(); ++i) {
Ref<Material> m = _prop_materials[i];
if (!m.is_valid()) {
continue;
}
Ref<Material> nm = m->duplicate();
cache->material_add(nm);
}
/*
#ifdef PROPS_PRESENT
for (int i = 0; i < chunk->prop_get_count(); ++i) {
Ref<PropData> prop = chunk->prop_get(i);
ERR_CONTINUE(!prop.is_valid());
cache->prop_add_textures(prop);
}
#endif
*/
#if MESH_DATA_RESOURCE_PRESENT
for (int i = 0; i < chunk->mesh_data_resource_get_count(); ++i) {
Ref<Texture> tex = chunk->mesh_data_resource_get_texture(i);
if (!tex.is_valid())
continue;
cache->additional_texture_add(tex);
}
#endif
_prop_material_cache[hash] = cache;
//unlock here, so if a different thread need the cache it will be able to immediately access the materials and surfaces when it gets it.
_prop_material_cache_mutex.unlock();
//this will generate the atlases
cache->refresh_rects();
}
Ref<VoxelMaterialCache> VoxelLibraryMergerPCM::_prop_material_cache_get(const int key) {
_prop_material_cache_mutex.lock();
ERR_FAIL_COND_V(!_prop_material_cache.has(key), Ref<VoxelMaterialCache>());
Ref<VoxelMaterialCache> c = _prop_material_cache[key];
_prop_material_cache_mutex.unlock();
return c;
}
void VoxelLibraryMergerPCM::_prop_material_cache_unref(const int key) {
_prop_material_cache_mutex.lock();
if (!_prop_material_cache.has(key)) {
return;
}
Ref<VoxelMaterialCachePCM> cc = _prop_material_cache[key];
if (!cc.is_valid()) {
return;
}
cc->dec_ref_count();
if (cc->get_ref_count() <= 0) {
_prop_material_cache.erase(key);
}
_prop_material_cache_mutex.unlock();
}
int VoxelLibraryMergerPCM::get_texture_flags() const {
return _packer->get_texture_flags();
}
void VoxelLibraryMergerPCM::set_texture_flags(const int flags) {
_packer->set_texture_flags(flags);
_prop_packer->set_texture_flags(flags);
}
int VoxelLibraryMergerPCM::get_max_atlas_size() const {
return _packer->get_max_atlas_size();
}
void VoxelLibraryMergerPCM::set_max_atlas_size(const int size) {
_packer->set_max_atlas_size(size);
_prop_packer->set_max_atlas_size(size);
}
bool VoxelLibraryMergerPCM::get_keep_original_atlases() const {
return _packer->get_keep_original_atlases();
}
void VoxelLibraryMergerPCM::set_keep_original_atlases(const bool value) {
_packer->set_keep_original_atlases(value);
_prop_packer->set_keep_original_atlases(value);
}
Color VoxelLibraryMergerPCM::get_background_color() const {
return _packer->get_background_color();
}
void VoxelLibraryMergerPCM::set_background_color(const Color &color) {
_packer->set_background_color(color);
_prop_packer->set_background_color(color);
}
int VoxelLibraryMergerPCM::get_margin() const {
return _packer->get_margin();
}
void VoxelLibraryMergerPCM::set_margin(const int margin) {
_packer->set_margin(margin);
_prop_packer->set_margin(margin);
}
//Surfaces
Ref<VoxelSurface> VoxelLibraryMergerPCM::voxel_surface_get(const int index) {
ERR_FAIL_INDEX_V(index, _voxel_surfaces.size(), Ref<VoxelSurface>(NULL));
return _voxel_surfaces[index];
}
void VoxelLibraryMergerPCM::voxel_surface_add(Ref<VoxelSurface> value) {
ERR_FAIL_COND(!value.is_valid());
value->set_library(Ref<VoxelLibraryMergerPCM>(this));
value->set_id(_voxel_surfaces.size());
_voxel_surfaces.push_back(value);
}
void VoxelLibraryMergerPCM::voxel_surface_set(const int index, Ref<VoxelSurface> value) {
ERR_FAIL_COND(index < 0);
if (_voxel_surfaces.size() < index) {
_voxel_surfaces.resize(index + 1);
}
if (_voxel_surfaces[index].is_valid()) {
_voxel_surfaces.get(index)->set_library(Ref<VoxelLibraryMergerPCM>(NULL));
}
if (value.is_valid()) {
value->set_library(Ref<VoxelLibraryMergerPCM>(this));
_voxel_surfaces.set(index, value);
}
}
void VoxelLibraryMergerPCM::voxel_surface_remove(const int index) {
_voxel_surfaces.remove(index);
}
int VoxelLibraryMergerPCM::voxel_surface_get_num() const {
return _voxel_surfaces.size();
}
void VoxelLibraryMergerPCM::voxel_surfaces_clear() {
_packer->clear();
for (int i = 0; i < _voxel_surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = _voxel_surfaces[i];
if (surface.is_valid()) {
surface->set_library(NULL);
}
}
_voxel_surfaces.clear();
}
Vector<Variant> VoxelLibraryMergerPCM::get_voxel_surfaces() {
VARIANT_ARRAY_GET(_voxel_surfaces);
}
void VoxelLibraryMergerPCM::set_voxel_surfaces(const Vector<Variant> &surfaces) {
_voxel_surfaces.clear();
for (int i = 0; i < surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = Ref<VoxelSurfaceMerger>(surfaces[i]);
if (surface.is_valid()) {
surface->set_library(Ref<VoxelLibraryMergerPCM>(this));
}
_voxel_surfaces.push_back(surface);
}
}
#ifdef PROPS_PRESENT
Ref<PropData> VoxelLibraryMergerPCM::get_prop(const int index) {
ERR_FAIL_INDEX_V(index, _props.size(), Ref<PropData>());
return _props[index];
}
void VoxelLibraryMergerPCM::add_prop(Ref<PropData> value) {
_props.push_back(value);
}
bool VoxelLibraryMergerPCM::has_prop(const Ref<PropData> &value) const {
return _props.find(value) != -1;
}
void VoxelLibraryMergerPCM::set_prop(const int index, const Ref<PropData> &value) {
ERR_FAIL_INDEX(index, _props.size());
_props.write[index] = value;
}
void VoxelLibraryMergerPCM::remove_prop(const int index) {
ERR_FAIL_INDEX(index, _props.size());
_props.remove(index);
}
int VoxelLibraryMergerPCM::get_num_props() const {
return _props.size();
}
void VoxelLibraryMergerPCM::clear_props() {
_props.clear();
}
Vector<Variant> VoxelLibraryMergerPCM::get_props() {
VARIANT_ARRAY_GET(_props);
}
void VoxelLibraryMergerPCM::set_props(const Vector<Variant> &props) {
VARIANT_ARRAY_SET(props, _props, PropData);
}
Rect2 VoxelLibraryMergerPCM::get_prop_uv_rect(const Ref<Texture> &texture) {
if (!texture.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Ref<AtlasTexture> at = _prop_packer->get_texture(texture);
if (!at.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Rect2 region = at->get_region();
Ref<Texture> tex = at->get_atlas();
if (!tex.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Ref<Image> image = tex->get_data();
if (!image.is_valid()) {
return Rect2(0, 0, 1, 1);
}
float w = image->get_width();
float h = image->get_height();
region.position = Size2(region.position.x / w, region.position.y / h);
region.size = Size2(region.size.x / w, region.size.y / h);
return region;
}
Ref<TexturePacker> VoxelLibraryMergerPCM::get_prop_packer() {
return _prop_packer;
}
#endif
void VoxelLibraryMergerPCM::refresh_rects() {
bool texture_added = false;
for (int i = 0; i < _voxel_surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = Ref<VoxelSurfaceMerger>(_voxel_surfaces[i]);
if (surface.is_valid()) {
for (int j = 0; j < VoxelSurface::VOXEL_SIDES_COUNT; ++j) {
Ref<Texture> tex = surface->get_texture(static_cast<VoxelSurface::VoxelSurfaceSides>(j));
if (!tex.is_valid())
continue;
if (!_packer->contains_texture(tex)) {
texture_added = true;
surface->set_region(static_cast<VoxelSurface::VoxelSurfaceSides>(j), _packer->add_texture(tex));
} else {
surface->set_region(static_cast<VoxelSurface::VoxelSurfaceSides>(j), _packer->get_texture(tex));
}
}
}
}
if (texture_added) {
_packer->merge();
ERR_FAIL_COND(_packer->get_texture_count() == 0);
Ref<Texture> tex = _packer->get_generated_texture(0);
setup_material_albedo(MATERIAL_INDEX_VOXELS, tex);
setup_material_albedo(MATERIAL_INDEX_LIQUID, tex);
}
#ifdef PROPS_PRESENT
//todo add this back
//texture_added = false;
for (int i = 0; i < _props.size(); i++) {
Ref<PropData> prop = _props.get(i);
if (prop.is_valid()) {
if (process_prop_textures(prop))
texture_added = true;
}
}
//if (texture_added) {
if (_prop_packer->get_texture_count() > 0) {
_prop_packer->merge();
//ERR_FAIL_COND(_prop_packer->get_texture_count() == 0);
Ref<Texture> tex = _prop_packer->get_generated_texture(0);
setup_material_albedo(MATERIAL_INDEX_PROP, tex);
}
#endif
for (int i = 0; i < _voxel_surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = _voxel_surfaces[i];
if (surface.is_valid()) {
surface->refresh_rects();
}
}
set_initialized(true);
}
void VoxelLibraryMergerPCM::_setup_material_albedo(const int material_index, const Ref<Texture> &texture) {
Ref<SpatialMaterial> mat;
int count = 0;
switch (material_index) {
case MATERIAL_INDEX_VOXELS:
count = material_get_num();
break;
case MATERIAL_INDEX_LIQUID:
count = liquid_material_get_num();
break;
case MATERIAL_INDEX_PROP:
count = prop_material_get_num();
break;
}
for (int i = 0; i < count; ++i) {
switch (material_index) {
case MATERIAL_INDEX_VOXELS:
mat = material_get(i);
break;
case MATERIAL_INDEX_LIQUID:
mat = liquid_material_get(i);
break;
case MATERIAL_INDEX_PROP:
mat = prop_material_get(i);
break;
}
Ref<SpatialMaterial> spmat;
if (spmat.is_valid()) {
spmat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
return;
}
Ref<ShaderMaterial> shmat;
switch (material_index) {
case MATERIAL_INDEX_VOXELS:
shmat = material_get(i);
break;
case MATERIAL_INDEX_LIQUID:
shmat = liquid_material_get(i);
break;
case MATERIAL_INDEX_PROP:
shmat = prop_material_get(i);
break;
}
if (shmat.is_valid()) {
shmat->set_shader_param("texture_albedo", texture);
}
}
}
VoxelLibraryMergerPCM::VoxelLibraryMergerPCM() {
_packer.instance();
#if GODOT4
#warning implement
#else
_packer->set_texture_flags(Texture::FLAG_MIPMAPS | Texture::FLAG_FILTER);
#endif
_packer->set_max_atlas_size(1024);
_packer->set_keep_original_atlases(false);
_packer->set_margin(0);
_prop_packer.instance();
#if GODOT4
#warning implement
#else
_prop_packer->set_texture_flags(Texture::FLAG_MIPMAPS | Texture::FLAG_FILTER);
#endif
_prop_packer->set_max_atlas_size(1024);
_prop_packer->set_keep_original_atlases(false);
_prop_packer->set_margin(0);
}
VoxelLibraryMergerPCM::~VoxelLibraryMergerPCM() {
for (int i = 0; i < _voxel_surfaces.size(); ++i) {
Ref<VoxelSurface> surface = _voxel_surfaces[i];
if (surface.is_valid()) {
surface->set_library(Ref<VoxelLibraryMergerPCM>());
}
}
_voxel_surfaces.clear();
_packer->clear();
_packer.unref();
_prop_packer->clear();
_prop_packer.unref();
}
#ifdef PROPS_PRESENT
bool VoxelLibraryMergerPCM::process_prop_textures(Ref<PropData> prop) {
if (!prop.is_valid()) {
return false;
}
bool texture_added = false;
for (int i = 0; i < prop->get_prop_count(); ++i) {
Ref<PropDataMeshData> pdm = prop->get_prop(i);
if (pdm.is_valid()) {
Ref<Texture> tex = pdm->get_texture();
if (!tex.is_valid())
continue;
if (!_prop_packer->contains_texture(tex)) {
_prop_packer->add_texture(tex);
texture_added = true;
}
}
Ref<PropDataProp> pdp = prop->get_prop(i);
if (pdp.is_valid()) {
if (process_prop_textures(pdp))
texture_added = true;
}
}
return texture_added;
}
#endif
void VoxelLibraryMergerPCM::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_flags"), &VoxelLibraryMergerPCM::get_texture_flags);
ClassDB::bind_method(D_METHOD("set_texture_flags", "flags"), &VoxelLibraryMergerPCM::set_texture_flags);
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_texture_flags", "get_texture_flags");
ClassDB::bind_method(D_METHOD("get_max_atlas_size"), &VoxelLibraryMergerPCM::get_max_atlas_size);
ClassDB::bind_method(D_METHOD("set_max_atlas_size", "size"), &VoxelLibraryMergerPCM::set_max_atlas_size);
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_atlas_size"), "set_max_atlas_size", "get_max_atlas_size");
ClassDB::bind_method(D_METHOD("get_keep_original_atlases"), &VoxelLibraryMergerPCM::get_keep_original_atlases);
ClassDB::bind_method(D_METHOD("set_keep_original_atlases", "value"), &VoxelLibraryMergerPCM::set_keep_original_atlases);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_original_atlases"), "set_keep_original_atlases", "get_keep_original_atlases");
ClassDB::bind_method(D_METHOD("get_background_color"), &VoxelLibraryMergerPCM::get_background_color);
ClassDB::bind_method(D_METHOD("set_background_color", "color"), &VoxelLibraryMergerPCM::set_background_color);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_background_color", "get_background_color");
ClassDB::bind_method(D_METHOD("get_margin"), &VoxelLibraryMergerPCM::get_margin);
ClassDB::bind_method(D_METHOD("set_margin", "size"), &VoxelLibraryMergerPCM::set_margin);
ADD_PROPERTY(PropertyInfo(Variant::INT, "margin"), "set_margin", "get_margin");
ClassDB::bind_method(D_METHOD("get_voxel_surfaces"), &VoxelLibraryMergerPCM::get_voxel_surfaces);
ClassDB::bind_method(D_METHOD("set_voxel_surfaces"), &VoxelLibraryMergerPCM::set_voxel_surfaces);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "voxel_surfaces", PROPERTY_HINT_NONE, "17/17:VoxelSurfaceMerger", PROPERTY_USAGE_DEFAULT, "VoxelSurfaceMerger"), "set_voxel_surfaces", "get_voxel_surfaces");
#ifdef PROPS_PRESENT
ClassDB::bind_method(D_METHOD("get_props"), &VoxelLibraryMergerPCM::get_props);
ClassDB::bind_method(D_METHOD("set_props"), &VoxelLibraryMergerPCM::set_props);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "props", PROPERTY_HINT_NONE, "17/17:PropData", PROPERTY_USAGE_DEFAULT, "PropData"), "set_props", "get_props");
ClassDB::bind_method(D_METHOD("get_prop_uv_rect", "texture"), &VoxelLibraryMergerPCM::get_prop_uv_rect);
ClassDB::bind_method(D_METHOD("get_prop_packer"), &VoxelLibraryMergerPCM::get_prop_packer);
#endif
ClassDB::bind_method(D_METHOD("_setup_material_albedo", "material_index", "texture"), &VoxelLibraryMergerPCM::_setup_material_albedo);
}

View File

@ -0,0 +1,140 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef VOXEL_LIBRARY_MERGER_PCM_H
#define VOXEL_LIBRARY_MERGER_PCM_H
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/resource.h"
#include "core/templates/map.h"
#else
#include "core/resource.h"
#include "core/map.h"
#endif
#include "voxel_library.h"
#include "scene/resources/material.h"
#include "../data/voxel_light.h"
#include "voxel_surface_merger.h"
#include "core/os/mutex.h"
class VoxelSurfaceSimple;
class VoxelMesher;
class PackedScene;
class VoxelMaterialCache;
class VoxelMaterialCachePCM;
class TexturePacker;
class VoxelChunk;
//pcm = per chunk material
class VoxelLibraryMergerPCM : public VoxelLibrary {
GDCLASS(VoxelLibraryMergerPCM, VoxelLibrary);
public:
bool _supports_caching();
void _material_cache_get_key(Ref<VoxelChunk> chunk);
Ref<VoxelMaterialCache> _material_cache_get(const int key);
void _material_cache_unref(const int key);
void _prop_material_cache_get_key(Ref<VoxelChunk> chunk);
Ref<VoxelMaterialCache> _prop_material_cache_get(const int key);
void _prop_material_cache_unref(const int key);
int get_texture_flags() const;
void set_texture_flags(const int flags);
int get_max_atlas_size() const;
void set_max_atlas_size(const int size);
bool get_keep_original_atlases() const;
void set_keep_original_atlases(const bool value);
Color get_background_color() const;
void set_background_color(const Color &color);
int get_margin() const;
void set_margin(const int margin);
Ref<VoxelSurface> voxel_surface_get(const int index);
void voxel_surface_add(Ref<VoxelSurface> value);
void voxel_surface_set(const int index, Ref<VoxelSurface> value);
void voxel_surface_remove(const int index);
int voxel_surface_get_num() const;
void voxel_surfaces_clear();
Vector<Variant> get_voxel_surfaces();
void set_voxel_surfaces(const Vector<Variant> &surfaces);
#ifdef PROPS_PRESENT
Ref<PropData> get_prop(const int index);
void add_prop(Ref<PropData> value);
bool has_prop(const Ref<PropData> &value) const;
void set_prop(const int index, const Ref<PropData> &value);
void remove_prop(const int index);
int get_num_props() const;
void clear_props();
Vector<Variant> get_props();
void set_props(const Vector<Variant> &props);
Rect2 get_prop_uv_rect(const Ref<Texture> &texture);
Ref<TexturePacker> get_prop_packer();
#endif
void refresh_rects();
void _setup_material_albedo(const int material_index, const Ref<Texture> &texture);
VoxelLibraryMergerPCM();
~VoxelLibraryMergerPCM();
protected:
#ifdef PROPS_PRESENT
bool process_prop_textures(Ref<PropData> prop);
#endif
static void _bind_methods();
Map<int, Ref<VoxelMaterialCachePCM> > _material_cache;
Map<int, Ref<VoxelMaterialCachePCM> > _prop_material_cache;
Vector<Ref<VoxelSurfaceMerger> > _voxel_surfaces;
#ifdef PROPS_PRESENT
Vector<Ref<PropData> > _props;
#endif
//todo remove these
Ref<TexturePacker> _packer;
Ref<TexturePacker> _prop_packer;
Mutex _material_cache_mutex;
Mutex _prop_material_cache_mutex;
};
#endif

View File

@ -72,7 +72,6 @@ public:
protected:
static void _bind_methods();
private:
Vector<Ref<VoxelSurfaceSimple> > _voxel_surfaces;
//atlas

View File

@ -0,0 +1,334 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "voxel_material_cache.h"
#include "../defines.h"
#ifdef PROPS_PRESENT
#include "../../props/props/prop_data.h"
#include "../../props/props/prop_data_prop.h"
#if MESH_DATA_RESOURCE_PRESENT
#include "../../mesh_data_resource/props/prop_data_mesh_data.h"
#endif
#endif
bool VoxelMaterialCache::get_initialized() {
return _initialized;
}
void VoxelMaterialCache::set_initialized(const bool value) {
_initialized = value;
}
int VoxelMaterialCache::get_ref_count() {
return _ref_count;
}
void VoxelMaterialCache::set_ref_count(const int value) {
_ref_count = value;
}
void VoxelMaterialCache::inc_ref_count() {
_ref_count += 1;
}
void VoxelMaterialCache::dec_ref_count() {
_ref_count -= 1;
}
//Materials
Ref<Material> VoxelMaterialCache::material_get(const int index) {
ERR_FAIL_INDEX_V(index, _materials.size(), Ref<Material>(NULL));
return _materials[index];
}
Ref<Material> VoxelMaterialCache::material_lod_get(const int index) {
ERR_FAIL_COND_V(_materials.size() == 0, Ref<Material>(NULL));
if (index < 0) {
return _materials[0];
}
if (index >= _materials.size()) {
return _materials[_materials.size() - 1];
}
return _materials[index];
}
void VoxelMaterialCache::material_add(const Ref<Material> &value) {
ERR_FAIL_COND(!value.is_valid());
_materials.push_back(value);
}
void VoxelMaterialCache::material_set(const int index, const Ref<Material> &value) {
ERR_FAIL_INDEX(index, _materials.size());
_materials.set(index, value);
}
void VoxelMaterialCache::material_remove(const int index) {
_materials.VREMOVE(index);
}
int VoxelMaterialCache::material_get_num() const {
return _materials.size();
}
void VoxelMaterialCache::materials_clear() {
_materials.clear();
}
Vector<Variant> VoxelMaterialCache::materials_get() {
VARIANT_ARRAY_GET(_materials);
}
void VoxelMaterialCache::materials_set(const Vector<Variant> &materials) {
_materials.clear();
for (int i = 0; i < materials.size(); i++) {
Ref<Material> material = Ref<Material>(materials[i]);
_materials.push_back(material);
}
}
//Surfaces
Ref<VoxelSurface> VoxelMaterialCache::surface_get(const int index) {
ERR_FAIL_INDEX_V(index, _surfaces.size(), Ref<VoxelSurface>());
return _surfaces[index];
}
Ref<VoxelSurface> VoxelMaterialCache::surface_id_get(const int id) {
Ref<VoxelSurface> surface;
for (int i = 0; i < _surfaces.size(); ++i) {
surface = _surfaces[i];
if (surface.is_valid()) {
if (surface->get_id() == id) {
break;
}
}
}
return surface;
}
void VoxelMaterialCache::surface_add(Ref<VoxelSurface> value) {
ERR_FAIL_COND(!value.is_valid());
_surfaces.push_back(value);
}
void VoxelMaterialCache::surface_set(int index, Ref<VoxelSurface> value) {
ERR_FAIL_COND(index < 0);
if (_surfaces.size() < index) {
_surfaces.resize(index + 1);
}
_surfaces.set(index, value);
}
void VoxelMaterialCache::surface_remove(const int index) {
_surfaces.VREMOVE(index);
}
int VoxelMaterialCache::surface_get_num() const {
return _surfaces.size();
}
void VoxelMaterialCache::surfaces_clear() {
_surfaces.clear();
}
void VoxelMaterialCache::additional_texture_add(const Ref<Texture> &texture) {
_additional_textures.push_back(texture);
}
void VoxelMaterialCache::additional_texture_remove(const Ref<Texture> &texture) {
for (int i = 0; i < _additional_textures.size(); ++i) {
if (_additional_textures[i] == texture) {
_additional_textures.VREMOVE(i);
return;
}
}
}
void VoxelMaterialCache::additional_texture_remove_index(const int index) {
ERR_FAIL_INDEX(index, _additional_textures.size());
_additional_textures.VREMOVE(index);
}
void VoxelMaterialCache::additional_textures_clear() {
_additional_textures.clear();
}
int VoxelMaterialCache::additional_texture_count() {
return _additional_textures.size();
}
Ref<Texture> VoxelMaterialCache::additional_texture_get(const int index) {
ERR_FAIL_INDEX_V(index, _additional_textures.size(), Ref<Texture>());
return _additional_textures[index];
}
Ref<AtlasTexture> VoxelMaterialCache::additional_texture_get_atlas(const int index) {
ERR_FAIL_INDEX_V(index, _additional_textures.size(), Ref<AtlasTexture>());
return additional_texture_get_atlas_tex(_additional_textures[index]);
}
Ref<AtlasTexture> VoxelMaterialCache::additional_texture_get_atlas_tex(const Ref<Texture> &texture) {
return Ref<AtlasTexture>();
}
Rect2 VoxelMaterialCache::additional_texture_get_uv_rect(const Ref<Texture> &texture) {
return Rect2(0, 0, 1, 1);
}
#ifdef PROPS_PRESENT
void VoxelMaterialCache::prop_add_textures(const Ref<PropData> &prop) {
if (!prop.is_valid()) {
return;
}
for (int i = 0; i < prop->get_prop_count(); ++i) {
#if MESH_DATA_RESOURCE_PRESENT
Ref<PropDataMeshData> pdm = prop->get_prop(i);
if (pdm.is_valid()) {
Ref<Texture> tex = pdm->get_texture();
if (!tex.is_valid())
continue;
additional_texture_add(tex);
}
#endif
Ref<PropDataProp> pdp = prop->get_prop(i);
if (pdp.is_valid()) {
prop_add_textures(pdp);
}
}
}
void VoxelMaterialCache::prop_remove_textures(const Ref<PropData> &prop) {
if (!prop.is_valid()) {
return;
}
for (int i = 0; i < prop->get_prop_count(); ++i) {
#if MESH_DATA_RESOURCE_PRESENT
Ref<PropDataMeshData> pdm = prop->get_prop(i);
if (pdm.is_valid()) {
Ref<Texture> tex = pdm->get_texture();
if (!tex.is_valid())
continue;
additional_texture_remove(tex);
}
#endif
Ref<PropDataProp> pdp = prop->get_prop(i);
if (pdp.is_valid()) {
prop_remove_textures(pdp);
}
}
}
#endif
void VoxelMaterialCache::refresh_rects() {
_initialized = true;
}
void VoxelMaterialCache::setup_material_albedo(Ref<Texture> texture) {
#if VERSION_MAJOR < 4
if (has_method("_setup_material_albedo")) {
call("_setup_material_albedo", texture);
}
#else
GDVIRTUAL_CALL(_setup_material_albedo, texture);
#endif
}
VoxelMaterialCache::VoxelMaterialCache() {
_ref_count = 0;
_initialized = false;
}
VoxelMaterialCache::~VoxelMaterialCache() {
_materials.clear();
_surfaces.clear();
}
void VoxelMaterialCache::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_initialized"), &VoxelMaterialCache::get_initialized);
ClassDB::bind_method(D_METHOD("set_initialized", "value"), &VoxelMaterialCache::set_initialized);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "initialized"), "set_initialized", "get_initialized");
ClassDB::bind_method(D_METHOD("get_ref_count"), &VoxelMaterialCache::get_ref_count);
ClassDB::bind_method(D_METHOD("set_ref_count", "value"), &VoxelMaterialCache::set_ref_count);
ADD_PROPERTY(PropertyInfo(Variant::INT, "mat_ref_count"), "set_ref_count", "get_ref_count");
ClassDB::bind_method(D_METHOD("inc_ref_count"), &VoxelMaterialCache::inc_ref_count);
ClassDB::bind_method(D_METHOD("dec_ref_count"), &VoxelMaterialCache::dec_ref_count);
#if VERSION_MAJOR < 4
BIND_VMETHOD(MethodInfo("_setup_material_albedo", PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture")));
#else
GDVIRTUAL_BIND(_setup_material_albedo, "texture");
#endif
ClassDB::bind_method(D_METHOD("material_get", "index"), &VoxelMaterialCache::material_get);
ClassDB::bind_method(D_METHOD("material_lod_get", "index"), &VoxelMaterialCache::material_lod_get);
ClassDB::bind_method(D_METHOD("material_add", "value"), &VoxelMaterialCache::material_add);
ClassDB::bind_method(D_METHOD("material_set", "index", "value"), &VoxelMaterialCache::material_set);
ClassDB::bind_method(D_METHOD("material_remove", "index"), &VoxelMaterialCache::material_remove);
ClassDB::bind_method(D_METHOD("material_get_num"), &VoxelMaterialCache::material_get_num);
ClassDB::bind_method(D_METHOD("materials_clear"), &VoxelMaterialCache::materials_clear);
ClassDB::bind_method(D_METHOD("materials_get"), &VoxelMaterialCache::materials_get);
ClassDB::bind_method(D_METHOD("materials_set"), &VoxelMaterialCache::materials_set);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "materials_set", "materials_get");
ClassDB::bind_method(D_METHOD("surface_get", "index"), &VoxelMaterialCache::surface_get);
ClassDB::bind_method(D_METHOD("surface_id_get", "index"), &VoxelMaterialCache::surface_id_get);
ClassDB::bind_method(D_METHOD("surface_add", "value"), &VoxelMaterialCache::surface_add);
ClassDB::bind_method(D_METHOD("surface_set", "index", "surface"), &VoxelMaterialCache::surface_set);
ClassDB::bind_method(D_METHOD("surface_remove", "index"), &VoxelMaterialCache::surface_remove);
ClassDB::bind_method(D_METHOD("surface_get_num"), &VoxelMaterialCache::surface_get_num);
ClassDB::bind_method(D_METHOD("surfaces_clear"), &VoxelMaterialCache::surfaces_clear);
ClassDB::bind_method(D_METHOD("additional_texture_add", "texture"), &VoxelMaterialCache::additional_texture_add);
ClassDB::bind_method(D_METHOD("additional_texture_remove", "texture"), &VoxelMaterialCache::additional_texture_remove);
ClassDB::bind_method(D_METHOD("additional_texture_remove_index", "index"), &VoxelMaterialCache::additional_texture_remove_index);
ClassDB::bind_method(D_METHOD("additional_textures_clear"), &VoxelMaterialCache::additional_textures_clear);
ClassDB::bind_method(D_METHOD("additional_texture_count"), &VoxelMaterialCache::additional_texture_count);
ClassDB::bind_method(D_METHOD("additional_texture_get", "index"), &VoxelMaterialCache::additional_texture_get);
ClassDB::bind_method(D_METHOD("additional_texture_get_atlas", "index"), &VoxelMaterialCache::additional_texture_get_atlas);
ClassDB::bind_method(D_METHOD("additional_texture_get_atlas_tex", "index"), &VoxelMaterialCache::additional_texture_get_atlas_tex);
ClassDB::bind_method(D_METHOD("additional_texture_get_uv_rect", "texture"), &VoxelMaterialCache::additional_texture_get_uv_rect);
#ifdef PROPS_PRESENT
ClassDB::bind_method(D_METHOD("prop_add_textures", "prop"), &VoxelMaterialCache::prop_add_textures);
ClassDB::bind_method(D_METHOD("prop_remove_textures", "prop"), &VoxelMaterialCache::prop_remove_textures);
#endif
ClassDB::bind_method(D_METHOD("refresh_rects"), &VoxelMaterialCache::refresh_rects);
ClassDB::bind_method(D_METHOD("setup_material_albedo", "texture"), &VoxelMaterialCache::setup_material_albedo);
}

View File

@ -0,0 +1,116 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef VOXEL_MATERIAL_CACHE_H
#define VOXEL_MATERIAL_CACHE_H
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/resource.h"
#include "core/math/color.h"
#include "core/templates/vector.h"
#else
#include "core/color.h"
#include "core/resource.h"
#include "core/vector.h"
#endif
#include "core/math/rect2.h"
#include "scene/resources/material.h"
#include "voxel_library.h"
#include "../defines.h"
class VoxelLibrary;
class VoxelMaterialCache : public Resource {
GDCLASS(VoxelMaterialCache, Resource)
public:
bool get_initialized();
void set_initialized(const bool value);
int get_ref_count();
void set_ref_count(const int value);
void inc_ref_count();
void dec_ref_count();
Ref<Material> material_get(const int index);
Ref<Material> material_lod_get(const int index);
void material_add(const Ref<Material> &value);
void material_set(const int index, const Ref<Material> &value);
void material_remove(const int index);
int material_get_num() const;
void materials_clear();
Vector<Variant> materials_get();
void materials_set(const Vector<Variant> &materials);
virtual Ref<VoxelSurface> surface_get(const int index);
virtual Ref<VoxelSurface> surface_id_get(const int id);
virtual void surface_add(Ref<VoxelSurface> value);
virtual void surface_set(const int index, Ref<VoxelSurface> value);
virtual void surface_remove(const int index);
virtual int surface_get_num() const;
virtual void surfaces_clear();
virtual void additional_texture_add(const Ref<Texture> &texture);
virtual void additional_texture_remove(const Ref<Texture> &texture);
virtual void additional_texture_remove_index(const int index);
virtual void additional_textures_clear();
virtual int additional_texture_count();
virtual Ref<Texture> additional_texture_get(const int index);
virtual Ref<AtlasTexture> additional_texture_get_atlas(const int index);
virtual Ref<AtlasTexture> additional_texture_get_atlas_tex(const Ref<Texture> &texture);
virtual Rect2 additional_texture_get_uv_rect(const Ref<Texture> &texture);
#ifdef PROPS_PRESENT
void prop_add_textures(const Ref<PropData> &prop);
void prop_remove_textures(const Ref<PropData> &prop);
#endif
virtual void refresh_rects();
void setup_material_albedo(Ref<Texture> texture);
#if VERSION_MAJOR >= 4
GDVIRTUAL1(_setup_material_albedo, Ref<Texture>);
#endif
VoxelMaterialCache();
~VoxelMaterialCache();
protected:
static void _bind_methods();
bool _initialized;
Vector<Ref<VoxelSurface>> _surfaces;
Vector<Ref<Material>> _materials;
Vector<Ref<Texture>> _additional_textures;
int _ref_count;
};
#endif

View File

@ -0,0 +1,232 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "voxel_material_cache_pcm.h"
#include "../../texture_packer/texture_packer.h"
#include "scene/resources/texture.h"
#include "voxel_surface.h"
#include "voxel_surface_merger.h"
int VoxelMaterialCachePCM::get_texture_flags() const {
return _packer->get_texture_flags();
}
void VoxelMaterialCachePCM::set_texture_flags(const int flags) {
_packer->set_texture_flags(flags);
}
int VoxelMaterialCachePCM::get_max_atlas_size() const {
return _packer->get_max_atlas_size();
}
void VoxelMaterialCachePCM::set_max_atlas_size(const int size) {
_packer->set_max_atlas_size(size);
}
bool VoxelMaterialCachePCM::get_keep_original_atlases() const {
return _packer->get_keep_original_atlases();
}
void VoxelMaterialCachePCM::set_keep_original_atlases(const bool value) {
_packer->set_keep_original_atlases(value);
}
Color VoxelMaterialCachePCM::get_background_color() const {
return _packer->get_background_color();
}
void VoxelMaterialCachePCM::set_background_color(const Color &color) {
_packer->set_background_color(color);
}
int VoxelMaterialCachePCM::get_margin() const {
return _packer->get_margin();
}
void VoxelMaterialCachePCM::set_margin(const int margin) {
_packer->set_margin(margin);
}
Ref<AtlasTexture> VoxelMaterialCachePCM::additional_texture_get_atlas_tex(const Ref<Texture> &texture) {
if (!_packer->contains_texture(texture)) {
return Ref<AtlasTexture>();
}
return _packer->get_texture(texture);
}
Rect2 VoxelMaterialCachePCM::additional_texture_get_uv_rect(const Ref<Texture> &texture) {
if (!texture.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Ref<AtlasTexture> at = _packer->get_texture(texture);
if (!at.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Rect2 region = at->get_region();
Ref<Texture> tex = at->get_atlas();
if (!tex.is_valid()) {
return Rect2(0, 0, 1, 1);
}
Ref<Image> image = tex->get_data();
if (!image.is_valid()) {
return Rect2(0, 0, 1, 1);
}
float w = image->get_width();
float h = image->get_height();
region.position = Size2(region.position.x / w, region.position.y / h);
region.size = Size2(region.size.x / w, region.size.y / h);
return region;
}
void VoxelMaterialCachePCM::refresh_rects() {
bool texture_added = false;
for (int i = 0; i < _surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = Ref<VoxelSurfaceMerger>(_surfaces[i]);
if (surface.is_valid()) {
for (int j = 0; j < VoxelSurface::VOXEL_SIDES_COUNT; ++j) {
Ref<Texture> tex = surface->get_texture(static_cast<VoxelSurface::VoxelSurfaceSides>(j));
if (!tex.is_valid())
continue;
if (!_packer->contains_texture(tex)) {
texture_added = true;
surface->set_region(static_cast<VoxelSurface::VoxelSurfaceSides>(j), _packer->add_texture(tex));
} else {
surface->set_region(static_cast<VoxelSurface::VoxelSurfaceSides>(j), _packer->get_texture(tex));
}
}
}
}
for (int i = 0; i < _additional_textures.size(); i++) {
Ref<Texture> tex = _additional_textures.get(i);
ERR_CONTINUE(!tex.is_valid());
if (!_packer->contains_texture(tex)) {
_packer->add_texture(tex);
texture_added = true;
}
}
if (texture_added) {
_packer->merge();
ERR_FAIL_COND(_packer->get_texture_count() == 0);
Ref<Texture> tex = _packer->get_generated_texture(0);
setup_material_albedo(tex);
}
for (int i = 0; i < _surfaces.size(); i++) {
Ref<VoxelSurfaceMerger> surface = _surfaces[i];
if (surface.is_valid()) {
surface->refresh_rects();
}
}
_initialized = true;
}
void VoxelMaterialCachePCM::_setup_material_albedo(Ref<Texture> texture) {
int count = material_get_num();
for (int i = 0; i < count; ++i) {
Ref<Material> m = material_get(i);
Ref<SpatialMaterial> spmat = m;
if (spmat.is_valid()) {
spmat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
return;
}
Ref<ShaderMaterial> shmat = m;
if (shmat.is_valid()) {
shmat->set_shader_param("texture_albedo", texture);
}
}
}
VoxelMaterialCachePCM::VoxelMaterialCachePCM() {
_packer.instance();
#if GODOT4
#warning implement
#else
_packer->set_texture_flags(Texture::FLAG_MIPMAPS | Texture::FLAG_FILTER);
#endif
_packer->set_max_atlas_size(1024);
_packer->set_keep_original_atlases(false);
_packer->set_margin(0);
}
VoxelMaterialCachePCM::~VoxelMaterialCachePCM() {
for (int i = 0; i < _surfaces.size(); ++i) {
Ref<VoxelSurface> surface = _surfaces[i];
if (surface.is_valid()) {
surface->set_library(Ref<VoxelLibrary>());
}
}
_surfaces.clear();
_packer->clear();
_packer.unref();
}
void VoxelMaterialCachePCM::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_flags"), &VoxelMaterialCachePCM::get_texture_flags);
ClassDB::bind_method(D_METHOD("set_texture_flags", "flags"), &VoxelMaterialCachePCM::set_texture_flags);
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_texture_flags", "get_texture_flags");
ClassDB::bind_method(D_METHOD("get_max_atlas_size"), &VoxelMaterialCachePCM::get_max_atlas_size);
ClassDB::bind_method(D_METHOD("set_max_atlas_size", "size"), &VoxelMaterialCachePCM::set_max_atlas_size);
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_atlas_size"), "set_max_atlas_size", "get_max_atlas_size");
ClassDB::bind_method(D_METHOD("get_keep_original_atlases"), &VoxelMaterialCachePCM::get_keep_original_atlases);
ClassDB::bind_method(D_METHOD("set_keep_original_atlases", "value"), &VoxelMaterialCachePCM::set_keep_original_atlases);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_original_atlases"), "set_keep_original_atlases", "get_keep_original_atlases");
ClassDB::bind_method(D_METHOD("get_background_color"), &VoxelMaterialCachePCM::get_background_color);
ClassDB::bind_method(D_METHOD("set_background_color", "color"), &VoxelMaterialCachePCM::set_background_color);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_background_color", "get_background_color");
ClassDB::bind_method(D_METHOD("get_margin"), &VoxelMaterialCachePCM::get_margin);
ClassDB::bind_method(D_METHOD("set_margin", "size"), &VoxelMaterialCachePCM::set_margin);
ADD_PROPERTY(PropertyInfo(Variant::INT, "margin"), "set_margin", "get_margin");
ClassDB::bind_method(D_METHOD("_setup_material_albedo", "texture"), &VoxelMaterialCachePCM::_setup_material_albedo);
}

View File

@ -0,0 +1,84 @@
/*
Copyright (c) 2019-2022 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef VOXEL_MATERIAL_CACHE_PCM_H
#define VOXEL_MATERIAL_CACHE_PCM_H
#include "voxel_material_cache.h"
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/resource.h"
#include "core/math/color.h"
#include "core/templates/vector.h"
#else
#include "core/color.h"
#include "core/resource.h"
#include "core/vector.h"
#endif
#include "core/math/rect2.h"
#include "scene/resources/material.h"
#include "../defines.h"
class VoxelSurface;
class TexturePacker;
class PropData;
class VoxelMaterialCachePCM : public VoxelMaterialCache {
GDCLASS(VoxelMaterialCachePCM, VoxelMaterialCache);
public:
int get_texture_flags() const;
void set_texture_flags(const int flags);
int get_max_atlas_size() const;
void set_max_atlas_size(const int size);
bool get_keep_original_atlases() const;
void set_keep_original_atlases(const bool value);
Color get_background_color() const;
void set_background_color(const Color &color);
int get_margin() const;
void set_margin(const int margin);
Ref<AtlasTexture> additional_texture_get_atlas_tex(const Ref<Texture> &texture);
Rect2 additional_texture_get_uv_rect(const Ref<Texture> &texture);
void refresh_rects();
void _setup_material_albedo(Ref<Texture> texture);
VoxelMaterialCachePCM();
~VoxelMaterialCachePCM();
protected:
static void _bind_methods();
Ref<TexturePacker> _packer;
};
#endif

View File

@ -27,10 +27,13 @@ SOFTWARE.
#include "library/voxel_library.h"
#include "library/voxel_library_simple.h"
#include "library/voxel_material_cache.h"
#ifdef TEXTURE_PACKER_PRESENT
#include "library/voxel_surface_merger.h"
#include "library/voxel_library_merger.h"
#include "library/voxel_library_merger_pcm.h"
#include "library/voxel_material_cache_pcm.h"
#include "library/voxel_surface_merger.h"
#endif
#include "data/voxel_light.h"
@ -90,9 +93,13 @@ void register_voxelman_types() {
ClassDB::register_class<VoxelLibrary>();
ClassDB::register_class<VoxelLibrarySimple>();
ClassDB::register_class<VoxelMaterialCache>();
#ifdef TEXTURE_PACKER_PRESENT
ClassDB::register_class<VoxelSurfaceMerger>();
ClassDB::register_class<VoxelLibraryMerger>();
ClassDB::register_class<VoxelLibraryMergerPCM>();
ClassDB::register_class<VoxelMaterialCachePCM>();
#endif
ClassDB::register_class<VoxelLight>();

View File

@ -188,6 +188,48 @@ _FORCE_INLINE_ void VoxelChunk::set_margin_end(const int value) {
_margin_end = value;
}
int VoxelChunk::material_cache_key_get() const {
return _material_cache_key;
}
void VoxelChunk::material_cache_key_set(const int value) {
_material_cache_key = value;
}
bool VoxelChunk::material_cache_key_has() const {
return _material_cache_key_has;
}
void VoxelChunk::material_cache_key_has_set(const bool value) {
_material_cache_key_has = value;
}
int VoxelChunk::liquid_material_cache_key_get() const {
return _liquid_material_cache_key;
}
void VoxelChunk::liquid_material_cache_key_set(const int value) {
_liquid_material_cache_key = value;
}
bool VoxelChunk::liquid_material_cache_key_has() const {
return _liquid_material_cache_key_has;
}
void VoxelChunk::liquid_material_cache_key_has_set(const bool value) {
_liquid_material_cache_key_has = value;
}
int VoxelChunk::prop_material_cache_key_get() const {
return _prop_material_cache_key;
}
void VoxelChunk::prop_material_cache_key_set(const int value) {
_prop_material_cache_key = value;
}
bool VoxelChunk::prop_material_cache_key_has() const {
return _prop_material_cache_key_has;
}
void VoxelChunk::prop_material_cache_key_has_set(const bool value) {
_prop_material_cache_key_has = value;
}
Ref<VoxelLibrary> VoxelChunk::get_library() {
return _library;
}
@ -1137,6 +1179,15 @@ VoxelChunk::VoxelChunk() {
_margin_start = 0;
_margin_end = 0;
_material_cache_key = 0;
_material_cache_key_has = false;
_liquid_material_cache_key = 0;
_liquid_material_cache_key_has = false;
_prop_material_cache_key = 0;
_prop_material_cache_key_has = false;
_current_job = -1;
_queued_generation = false;
@ -1456,6 +1507,30 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin_end"), &VoxelChunk::set_margin_end);
ADD_PROPERTY(PropertyInfo(Variant::INT, "margin_end"), "set_margin_end", "get_margin_end");
ClassDB::bind_method(D_METHOD("material_cache_key_get"), &VoxelChunk::material_cache_key_get);
ClassDB::bind_method(D_METHOD("material_cache_key_set"), &VoxelChunk::material_cache_key_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "material_cache_key"), "material_cache_key_set", "material_cache_key_get");
ClassDB::bind_method(D_METHOD("material_cache_key_has"), &VoxelChunk::material_cache_key_has);
ClassDB::bind_method(D_METHOD("material_cache_key_has_set"), &VoxelChunk::material_cache_key_has_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "material_cache_key_has"), "material_cache_key_has_set", "material_cache_key_has");
ClassDB::bind_method(D_METHOD("liquid_material_cache_key_get"), &VoxelChunk::liquid_material_cache_key_get);
ClassDB::bind_method(D_METHOD("liquid_material_cache_key_set"), &VoxelChunk::liquid_material_cache_key_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "liquid_material_cache_key"), "liquid_material_cache_key_set", "liquid_material_cache_key_get");
ClassDB::bind_method(D_METHOD("liquid_material_cache_key_has"), &VoxelChunk::liquid_material_cache_key_has);
ClassDB::bind_method(D_METHOD("liquid_material_cache_key_has_set"), &VoxelChunk::liquid_material_cache_key_has_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "liquid_material_cache_key_has"), "liquid_material_cache_key_has_set", "liquid_material_cache_key_has");
ClassDB::bind_method(D_METHOD("prop_material_cache_key_get"), &VoxelChunk::prop_material_cache_key_get);
ClassDB::bind_method(D_METHOD("prop_material_cache_key_set"), &VoxelChunk::prop_material_cache_key_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "prop_material_cache_key"), "prop_material_cache_key_set", "prop_material_cache_key_get");
ClassDB::bind_method(D_METHOD("prop_material_cache_key_has"), &VoxelChunk::prop_material_cache_key_has);
ClassDB::bind_method(D_METHOD("prop_material_cache_key_has_set"), &VoxelChunk::prop_material_cache_key_has_set);
ADD_PROPERTY(PropertyInfo(Variant::INT, "prop_material_cache_key_has"), "prop_material_cache_key_has_set", "prop_material_cache_key_has");
ClassDB::bind_method(D_METHOD("get_library"), &VoxelChunk::get_library);
ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLibrary"), "set_library", "get_library");

View File

@ -67,8 +67,8 @@ include_pool_vector
typedef class Transform3D Transform;
#endif
#include "../library/voxel_surface.h"
#include "../library/voxel_library.h"
#include "../library/voxel_surface.h"
; //hackfix for a clang format issue
class VoxelJob;
@ -144,6 +144,24 @@ public:
void set_margin_start(const int value);
void set_margin_end(const int value);
int material_cache_key_get() const;
void material_cache_key_set(const int value);
bool material_cache_key_has() const;
void material_cache_key_has_set(const bool value);
int liquid_material_cache_key_get() const;
void liquid_material_cache_key_set(const int value);
bool liquid_material_cache_key_has() const;
void liquid_material_cache_key_has_set(const bool value);
int prop_material_cache_key_get() const;
void prop_material_cache_key_set(const int value);
bool prop_material_cache_key_has() const;
void prop_material_cache_key_has_set(const bool value);
Ref<VoxelLibrary> get_library();
void set_library(const Ref<VoxelLibrary> &value);
@ -395,6 +413,15 @@ protected:
int _margin_start;
int _margin_end;
int _material_cache_key;
bool _material_cache_key_has;
int _liquid_material_cache_key;
bool _liquid_material_cache_key_has;
int _prop_material_cache_key;
bool _prop_material_cache_key_has;
Vector<uint8_t *> _channels;
float _voxel_scale;