Namespaced every registered class

This commit is contained in:
Marc Gilleron 2022-01-09 22:13:10 +00:00
parent 589d692cde
commit b67ca3d903
121 changed files with 692 additions and 376 deletions

View File

@ -13,7 +13,7 @@ There are no release builds yet. We need to setup Github Releases for this. For
Release builds correspond to a development milestone. Each has a branch (for example `godot3.4`, `godot3.3`...). They are feature freezes and may only receive bug fixes later on. Usually, they are made at the same time a new version of Godot comes out.
Because the plugin is a module at the moment, and we don't have the same pipeline as the Godot devs, it comes as a whole custom build of the Godot editor, and might differ a little from the official version.
Not all export templates might be available yet. So you can develop your game and test it with the editor, but if you want to export it, you may need to compile the templates yourself.
The engine is massive and targets a lot of platforms, while our module is small in comparison and we don't have dedicated build containers, so not all export templates are available. You can develop your game and test it with the editor on main desktop platforms, but if you want to export it, you may need to compile the templates yourself.
### Development builds

View File

@ -156,10 +156,9 @@ In performance-critical areas which run a lot:
The intented namespaces are `zylann::` as main, and `zylann::voxel::` for voxel-related stuff. There may be others for different parts of the module. Namespaces are a work in progress, so a lot of places still miss them.
Registered classes are largely prefixed with `Voxel`, and not namespaced yet.
Godot's core codebase is generally not using namespaces. Classes registered to the engine must have a unique name regardless of namespaces, so in this module, they are primarily used to wrap the rest of the code. It is however desirable for registered classes to be in a namespace as well for consistency, and to avoid having to type fully-qualified names all the time.
Registered classes are also namespaced, but are still largely prefixed with `Voxel`. Classes registered to the engine must have a unique name regardless of namespaces.
It should be possible to use namespaces around a module class, since Godot4 started using them [here](https://github.com/godotengine/godot/blob/a8a20a0e02c8459513542f77eaed9b7350812c94/core/core_bind.h#L47) for core bindings (the [reason](https://github.com/godotengine/godot/pull/51627) was very specific though). In GDExtension it was not tested yet, but if there is a problem we'll have to do a PR to fix it.
If a registered class needs the same name as an internal one, it can be placed into a `::gd` sub-namespace. On the other hand, internal classes can also be suffixed `Internal`.
### Version control

View File

@ -1,5 +1,7 @@
#include "voxel_raycast_result.h"
namespace zylann::voxel {
Vector3i VoxelRaycastResult::_b_get_position() const {
return position;
}
@ -21,3 +23,5 @@ void VoxelRaycastResult::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "previous_position"), "", "get_previous_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "", "get_distance");
}
} // namespace zylann::voxel

View File

@ -4,6 +4,8 @@
#include "../util/math/vector3i.h"
#include <core/object/ref_counted.h>
namespace zylann::voxel {
// This class exists only to make the script API nicer.
class VoxelRaycastResult : public RefCounted {
GDCLASS(VoxelRaycastResult, RefCounted)
@ -20,4 +22,6 @@ private:
static void _bind_methods();
};
} // namespace zylann::voxel
#endif // VOXEL_RAYCAST_RESULT_H

View File

@ -3,8 +3,7 @@
#include "../util/macros.h"
#include "../util/profiling.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelTool::VoxelTool() {
_sdf_scale = VoxelBufferInternal::get_sdf_quantization_scale(VoxelBufferInternal::DEFAULT_SDF_CHANNEL_DEPTH);
@ -344,3 +343,5 @@ void VoxelTool::_bind_methods() {
BIND_ENUM_CONSTANT(MODE_SET);
BIND_ENUM_CONSTANT(MODE_TEXTURE_PAINT);
}
} // namespace zylann::voxel

View File

@ -7,7 +7,9 @@
#include "funcs.h"
#include "voxel_raycast_result.h"
namespace zylann::voxel {
class VoxelBuffer;
}
namespace zylann::voxel::ops {
@ -82,6 +84,8 @@ struct TextureBlendSphereOp {
// TODO Need to review VoxelTool to account for transformed volumes
namespace zylann::voxel {
// High-level generic voxel edition utility.
// Ease of use comes at cost.
// It's not a class to instantiate alone, get it from the voxel objects you want to work with
@ -222,9 +226,11 @@ protected:
Mode _mode = MODE_ADD;
// Used on smooth terrain
zylann::voxel::ops::TextureParams _texture_params;
ops::TextureParams _texture_params;
};
VARIANT_ENUM_CAST(VoxelTool::Mode)
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelTool::Mode)
#endif // VOXEL_TOOL_H

View File

@ -3,8 +3,7 @@
#include "../util/profiling.h"
#include "funcs.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelToolBuffer::VoxelToolBuffer(Ref<VoxelBuffer> vb) {
ERR_FAIL_COND(vb.is_null());
@ -127,3 +126,5 @@ void VoxelToolBuffer::paste(
_buffer->get_buffer().copy_voxel_metadata_in_area(
p_voxels->get_buffer(), Box3i(Vector3i(), p_voxels->get_buffer().get_size()), p_pos);
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include "voxel_tool.h"
namespace zylann::voxel {
class VoxelToolBuffer : public VoxelTool {
GDCLASS(VoxelToolBuffer, VoxelTool)
public:
@ -29,4 +31,6 @@ private:
Ref<VoxelBuffer> _buffer;
};
} // namespace zylann::voxel
#endif // VOXEL_TOOL_BUFFER_H

View File

@ -14,8 +14,7 @@
#include <scene/3d/physics_body_3d.h>
#include <scene/main/timer.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelToolLodTerrain::VoxelToolLodTerrain(VoxelLodTerrain *terrain) : _terrain(terrain) {
ERR_FAIL_COND(terrain == nullptr);
@ -28,7 +27,8 @@ bool VoxelToolLodTerrain::is_area_editable(const Box3i &box) const {
return _terrain->is_area_editable(box);
}
template <typename Volume_F> float get_sdf_interpolated(const Volume_F &f, Vector3 pos) {
template <typename Volume_F>
float get_sdf_interpolated(const Volume_F &f, Vector3 pos) {
const Vector3i c = Vector3iUtil::from_floored(pos);
const float s000 = f(Vector3i(c.x, c.y, c.z));
@ -131,8 +131,7 @@ Ref<VoxelRaycastResult> VoxelToolLodTerrain::raycast(
// `voxel_raycast` operates on a discrete grid of cubic voxels, so to account for the smooth interpolation,
// we may offset the ray so that cubes act as if they were centered on the filtered result.
const Vector3 offset(0.5, 0.5, 0.5);
if (zylann::voxel_raycast(
pos + offset, dir, predicate, max_distance, hit_pos, prev_pos, hit_distance, hit_distance_prev)) {
if (voxel_raycast(pos + offset, dir, predicate, max_distance, hit_pos, prev_pos, hit_distance, hit_distance_prev)) {
// Approximate surface
float d = hit_distance;
@ -165,7 +164,7 @@ Ref<VoxelRaycastResult> VoxelToolLodTerrain::raycast(
return res;
}
namespace zylann::voxel::ops {
namespace ops {
struct DoSphere {
Vector3 center;
@ -217,7 +216,7 @@ struct DoSphere {
}
};
} //namespace zylann::voxel::ops
} //namespace ops
void VoxelToolLodTerrain::do_sphere(Vector3 center, float radius) {
VOXEL_PROFILE_SCOPE();
@ -256,12 +255,11 @@ void VoxelToolLodTerrain::do_sphere(Vector3 center, float radius) {
_post_edit(box);
}
namespace zylann::voxel {
template <typename Op_T> class VoxelToolAsyncEdit : public IThreadedTask {
template <typename Op_T>
class VoxelToolAsyncEdit : public IThreadedTask {
public:
VoxelToolAsyncEdit(Op_T op, std::shared_ptr<VoxelDataLodMap> data) : _op(op), _data(data) {
_tracker = gd_make_shared<zylann::AsyncDependencyTracker>(1);
_tracker = gd_make_shared<AsyncDependencyTracker>(1);
}
void run(ThreadedTaskContext ctx) override {
@ -293,8 +291,6 @@ private:
std::shared_ptr<AsyncDependencyTracker> _tracker;
};
} // namespace zylann::voxel
void VoxelToolLodTerrain::do_sphere_async(Vector3 center, float radius) {
ERR_FAIL_COND(_terrain == nullptr);
@ -387,8 +383,6 @@ void VoxelToolLodTerrain::set_raycast_binary_search_iterations(int iterations) {
_raycast_binary_search_iterations = math::clamp(iterations, 0, 16);
}
namespace zylann::voxel {
// Turns floating chunks of voxels into rigidbodies:
// Detects separate groups of connected voxels within a box. Each group fully contained in the box is removed from
// the source volume, and turned into a rigidbody.
@ -716,8 +710,6 @@ Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, Node *par
return nodes;
}
} // namespace zylann::voxel
Array VoxelToolLodTerrain::separate_floating_chunks(AABB world_box, Node *parent_node) {
ERR_FAIL_COND_V(_terrain == nullptr, Array());
ERR_FAIL_COND_V(!math::is_valid_size(world_box.size), Array());
@ -741,3 +733,5 @@ void VoxelToolLodTerrain::_bind_methods() {
D_METHOD("separate_floating_chunks", "box", "parent_node"), &VoxelToolLodTerrain::separate_floating_chunks);
ClassDB::bind_method(D_METHOD("do_sphere_async", "center", "radius"), &VoxelToolLodTerrain::do_sphere_async);
}
} // namespace zylann::voxel

View File

@ -3,11 +3,10 @@
#include "voxel_tool.h"
class VoxelLodTerrain;
namespace zylann::voxel {
class VoxelLodTerrain;
class VoxelDataMap;
}
class VoxelToolLodTerrain : public VoxelTool {
GDCLASS(VoxelToolLodTerrain, VoxelTool)
@ -45,4 +44,6 @@ private:
int _raycast_binary_search_iterations = 0;
};
} // namespace zylann::voxel
#endif // VOXEL_TOOL_LOD_TERRAIN_H

View File

@ -5,8 +5,7 @@
#include "../util/godot/funcs.h"
#include "../util/voxel_raycast.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelToolTerrain::VoxelToolTerrain() {}
@ -412,3 +411,5 @@ void VoxelToolTerrain::_bind_methods() {
ClassDB::bind_method(D_METHOD("for_each_voxel_metadata_in_area", "voxel_area", "callback"),
&VoxelToolTerrain::for_each_voxel_metadata_in_area);
}
} // namespace zylann::voxel

View File

@ -3,12 +3,11 @@
#include "voxel_tool.h"
namespace zylann::voxel {
class VoxelTerrain;
class VoxelLibrary;
namespace zylann::voxel {
class VoxelDataMap;
}
class VoxelToolTerrain : public VoxelTool {
GDCLASS(VoxelToolTerrain, VoxelTool)
@ -36,9 +35,8 @@ public:
// For easier unit testing (the regular one needs a terrain setup etc, harder to test atm)
// The `_static` suffix is because it otherwise conflicts with the non-static method when registering the class
static void run_blocky_random_tick_static(zylann::voxel::VoxelDataMap &map, Box3i voxel_box,
const VoxelLibrary &lib, int voxel_count, int batch_count, void *callback_data,
bool (*callback)(void *, Vector3i, int64_t));
static void run_blocky_random_tick_static(VoxelDataMap &map, Box3i voxel_box, const VoxelLibrary &lib,
int voxel_count, int batch_count, void *callback_data, bool (*callback)(void *, Vector3i, int64_t));
void for_each_voxel_metadata_in_area(AABB voxel_area, const Callable &callback);
@ -55,4 +53,6 @@ private:
VoxelTerrain *_terrain = nullptr;
};
} // namespace zylann::voxel
#endif // VOXEL_TOOL_TERRAIN_H

View File

@ -10,6 +10,8 @@
#define VOXEL_ARRAY_LENGTH(a) (sizeof(a) / sizeof(a[0]))
namespace zylann::voxel {
namespace {
struct ThirdParty {
const char *name;
@ -300,3 +302,5 @@ void VoxelAboutWindow::_bind_methods() {
// ClassDB::bind_method(
// D_METHOD("_on_third_party_list_item_selected"), &VoxelAboutWindow::_on_third_party_list_item_selected);
}
} // namespace zylann::voxel

View File

@ -6,6 +6,8 @@
class TextureRect;
class RichTextLabel;
namespace zylann::voxel {
class VoxelAboutWindow : public AcceptDialog {
GDCLASS(VoxelAboutWindow, AcceptDialog)
public:
@ -24,4 +26,6 @@ private:
RichTextLabel *_third_party_rich_text_label;
};
} // namespace zylann::voxel
#endif // VOXEL_ABOUT_WINDOW_H

View File

@ -4,6 +4,8 @@
#include <core/core_string_names.h>
#include <editor/editor_scale.h>
namespace zylann {
class FastNoise2Viewer : public Control {
GDCLASS(FastNoise2Viewer, Control)
public:
@ -115,3 +117,5 @@ FastNoise2EditorPlugin::FastNoise2EditorPlugin(EditorNode *p_node) {
plugin.instantiate();
add_inspector_plugin(plugin);
}
} // namespace zylann

View File

@ -3,6 +3,8 @@
#include <editor/editor_plugin.h>
namespace zylann {
class FastNoise2EditorPlugin : public EditorPlugin {
GDCLASS(FastNoise2EditorPlugin, EditorPlugin)
public:
@ -13,4 +15,6 @@ public:
FastNoise2EditorPlugin(EditorNode *p_node);
};
} // namespace zylann
#endif // FAST_NOISE_2_EDITOR_PLUGIN_H

View File

@ -5,6 +5,8 @@
#include <core/core_string_names.h>
#include <editor/editor_scale.h>
namespace zylann {
class FastNoiseLiteViewer : public Control {
GDCLASS(FastNoiseLiteViewer, Control)
public:
@ -182,3 +184,5 @@ FastNoiseLiteEditorPlugin::FastNoiseLiteEditorPlugin(EditorNode *p_node) {
plugin.instantiate();
add_inspector_plugin(plugin);
}
} // namespace zylann

View File

@ -3,6 +3,8 @@
#include <editor/editor_plugin.h>
namespace zylann {
class FastNoiseLiteEditorPlugin : public EditorPlugin {
GDCLASS(FastNoiseLiteEditorPlugin, EditorPlugin)
public:
@ -13,4 +15,6 @@ public:
FastNoiseLiteEditorPlugin(EditorNode *p_node);
};
} // namespace zylann
#endif // FAST_NOISE_LITE_EDITOR_PLUGIN_H

View File

@ -14,15 +14,14 @@
#include <scene/gui/grid_container.h>
#include <scene/gui/label.h>
namespace zylann::voxel {
const char *VoxelGraphEditor::SIGNAL_NODE_SELECTED = "node_selected";
const char *VoxelGraphEditor::SIGNAL_NOTHING_SELECTED = "nothing_selected";
const char *VoxelGraphEditor::SIGNAL_NODES_DELETED = "nodes_deleted";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using namespace zylann;
using namespace voxel;
// Shows a 2D slice of the 3D set of values coming from an output port
class VoxelGraphEditorNodePreview : public VBoxContainer {
GDCLASS(VoxelGraphEditorNodePreview, VBoxContainer)
@ -1006,3 +1005,5 @@ void VoxelGraphEditor::_bind_methods() {
ADD_SIGNAL(MethodInfo(SIGNAL_NOTHING_SELECTED, PropertyInfo(Variant::INT, "nothing_selected")));
ADD_SIGNAL(MethodInfo(SIGNAL_NODES_DELETED, PropertyInfo(Variant::INT, "nodes_deleted")));
}
} // namespace zylann::voxel

View File

@ -4,14 +4,17 @@
#include "../voxel_debug.h"
#include <scene/gui/control.h>
class VoxelGeneratorGraph;
class GraphEdit;
class PopupMenu;
class AcceptDialog;
class UndoRedo;
class Node3D;
namespace zylann::voxel {
class VoxelGeneratorGraph;
class VoxelRangeAnalysisDialog;
class VoxelNode;
class Node3D;
class VoxelGraphEditor : public Control {
GDCLASS(VoxelGraphEditor, Control)
@ -79,7 +82,9 @@ private:
bool _nothing_selected_check_scheduled = false;
float _time_before_preview_update = 0.f;
Node3D *_voxel_node = nullptr;
zylann::DebugRenderer _debug_renderer;
DebugRenderer _debug_renderer;
};
} // namespace zylann::voxel
#endif // VOXEL_GRAPH_EDITOR_H

View File

@ -7,6 +7,8 @@
#include <editor/editor_data.h>
#include <editor/editor_scale.h>
namespace zylann::voxel {
VoxelGraphEditorPlugin::VoxelGraphEditorPlugin(EditorNode *p_node) {
//EditorInterface *ed = get_editor_interface();
_graph_editor = memnew(VoxelGraphEditor);
@ -131,3 +133,5 @@ void VoxelGraphEditorPlugin::_bind_methods() {
// D_METHOD("_on_graph_editor_nothing_selected"), &VoxelGraphEditorPlugin::_on_graph_editor_nothing_selected);
ClassDB::bind_method(D_METHOD("_hide_deferred"), &VoxelGraphEditorPlugin::_hide_deferred);
}
} // namespace zylann::voxel

View File

@ -3,8 +3,9 @@
#include <editor/editor_plugin.h>
namespace zylann::voxel {
class VoxelGraphEditor;
//class ToolButton;
class VoxelGraphEditorPlugin : public EditorPlugin {
GDCLASS(VoxelGraphEditorPlugin, EditorPlugin)
@ -28,4 +29,6 @@ private:
bool _deferred_visibility_scheduled = false;
};
} // namespace zylann::voxel
#endif // VOXEL_GRAPH_EDITOR_PLUGIN_H

View File

@ -3,8 +3,7 @@
#include "../../util/macros.h"
#include <core/object/undo_redo.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
void VoxelGraphNodeInspectorWrapper::setup(Ref<VoxelGeneratorGraph> p_graph, uint32_t p_node_id, UndoRedo *ur) {
_graph = p_graph;
@ -151,3 +150,5 @@ bool VoxelGraphNodeInspectorWrapper::_dont_undo_redo() const {
void VoxelGraphNodeInspectorWrapper::_bind_methods() {
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &VoxelGraphNodeInspectorWrapper::_dont_undo_redo);
}
} // namespace zylann::voxel

View File

@ -6,6 +6,8 @@
class UndoRedo;
namespace zylann::voxel {
// Nodes aren't resources so this translates them into a form the inspector can understand.
// This makes it easier to support undo/redo and sub-resources.
// WARNING: `AnimationPlayer` will allow to keyframe properties, but there really is no support for that.
@ -27,8 +29,10 @@ private:
static void _bind_methods();
Ref<VoxelGeneratorGraph> _graph;
uint32_t _node_id = zylann::ProgramGraph::NULL_ID;
uint32_t _node_id = ProgramGraph::NULL_ID;
UndoRedo *_undo_redo = nullptr;
};
} // namespace zylann::voxel
#endif // VOXEL_GRAPH_NODE_INSPECTOR_WRAPPER_H

View File

@ -6,14 +6,14 @@
#include <scene/gui/menu_button.h>
#include <scene/resources/primitive_meshes.h>
namespace {
namespace zylann::voxel {
enum Buttons {
BUTTON_ADD_MULTIMESH_ITEM,
BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE,
BUTTON_ADD_SCENE_ITEM,
BUTTON_REMOVE_ITEM
};
} // namespace
bool VoxelInstanceLibraryEditorInspectorPlugin::can_handle(Object *p_object) {
return Object::cast_to<VoxelInstanceLibrary>(p_object) != nullptr;
@ -287,3 +287,5 @@ void VoxelInstanceLibraryEditorPlugin::_bind_methods() {
// ClassDB::bind_method(D_METHOD("_on_open_scene_dialog_file_selected", "fpath"),
// &VoxelInstanceLibraryEditorPlugin::_on_open_scene_dialog_file_selected);
}
} // namespace zylann::voxel

View File

@ -7,6 +7,9 @@
class Control;
class MenuButton;
class ConfirmationDialog;
namespace zylann::voxel {
class VoxelInstanceLibraryEditorPlugin;
class VoxelInstanceLibraryEditorInspectorPlugin : public EditorInspectorPlugin {
@ -25,7 +28,9 @@ private:
class VoxelInstanceLibraryEditorPlugin : public EditorPlugin {
GDCLASS(VoxelInstanceLibraryEditorPlugin, EditorPlugin)
public:
virtual String get_name() const { return "VoxelInstanceLibrary"; }
virtual String get_name() const {
return "VoxelInstanceLibrary";
}
VoxelInstanceLibraryEditorPlugin(EditorNode *p_node);
@ -57,4 +62,6 @@ private:
Ref<VoxelInstanceLibraryEditorInspectorPlugin> _inspector_plugin;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCE_LIBRARY_EDITOR_PLUGIN_H

View File

@ -1,6 +1,8 @@
#include "voxel_instancer_editor_plugin.h"
#include "../../terrain/instancing/voxel_instancer.h"
namespace zylann::voxel {
VoxelInstancerEditorPlugin::VoxelInstancerEditorPlugin(EditorNode *p_node) {}
bool VoxelInstancerEditorPlugin::handles(Object *p_object) const {
@ -23,3 +25,5 @@ void VoxelInstancerEditorPlugin::make_visible(bool visible) {
}
}
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include <editor/editor_plugin.h>
namespace zylann::voxel {
class VoxelInstancer;
class VoxelInstancerEditorPlugin : public EditorPlugin {
@ -18,4 +20,6 @@ private:
VoxelInstancer *_node = nullptr;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCER_EDITOR_PLUGIN_H

View File

@ -9,8 +9,7 @@
#include <scene/3d/camera_3d.h>
#include <scene/gui/menu_button.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
class VoxelTerrainEditorTaskIndicator : public HBoxContainer {
GDCLASS(VoxelTerrainEditorTaskIndicator, HBoxContainer)
@ -351,3 +350,5 @@ void VoxelTerrainEditorPlugin::_bind_methods() {
// ClassDB::bind_method(D_METHOD("_on_terrain_tree_entered"), &VoxelTerrainEditorPlugin::_on_terrain_tree_entered);
// ClassDB::bind_method(D_METHOD("_on_terrain_tree_exited"), &VoxelTerrainEditorPlugin::_on_terrain_tree_exited);
}
} // namespace zylann::voxel

View File

@ -4,6 +4,9 @@
#include <editor/editor_plugin.h>
class MenuButton;
namespace zylann::voxel {
class VoxelAboutWindow;
class VoxelNode;
class VoxelTerrainEditorTaskIndicator;
@ -48,4 +51,6 @@ private:
VoxelTerrainEditorTaskIndicator *_task_indicator = nullptr;
};
} // namespace zylann::voxel
#endif // VOXEL_TERRAIN_EDITOR_PLUGIN_H

View File

@ -2,6 +2,8 @@
#include "vox_importer.h"
#include "vox_mesh_importer.h"
namespace zylann::voxel::magica {
VoxEditorPlugin::VoxEditorPlugin(EditorNode *p_node) {
Ref<VoxelVoxImporter> vox_scene_importer;
vox_scene_importer.instantiate();
@ -12,3 +14,5 @@ VoxEditorPlugin::VoxEditorPlugin(EditorNode *p_node) {
vox_mesh_importer.instantiate();
ResourceFormatImporter::get_singleton()->add_importer(vox_mesh_importer);
}
} // namespace zylann::voxel::magica

View File

@ -3,10 +3,14 @@
#include <editor/editor_plugin.h>
namespace zylann::voxel::magica {
class VoxEditorPlugin : public EditorPlugin {
GDCLASS(VoxEditorPlugin, EditorPlugin)
public:
VoxEditorPlugin(EditorNode *p_node);
};
} // namespace zylann::voxel::magica
#endif // VOX_EDITOR_PLUGIN_H

View File

@ -13,8 +13,7 @@
#include <scene/resources/mesh.h>
#include <scene/resources/packed_scene.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel::magica {
String VoxelVoxImporter::get_importer_name() const {
return "VoxelVoxImporter";
@ -65,7 +64,8 @@ bool VoxelVoxImporter::get_option_visibility(
return true;
}
static void add_mesh_instance(Ref<Mesh> mesh, Node *parent, Node *owner, Vector3 offset, bool p_enable_baked_lighting) {
static void add_mesh_instance(
Ref<Mesh> mesh, ::Node *parent, ::Node *owner, Vector3 offset, bool p_enable_baked_lighting) {
MeshInstance3D *mesh_instance = memnew(MeshInstance3D);
mesh_instance->set_mesh(mesh);
parent->add_child(mesh_instance);
@ -82,8 +82,6 @@ struct VoxMesh {
Vector3 pivot;
};
namespace zylann::voxel::magica {
static Error process_scene_node_recursively(const Data &data, int node_id, Node3D *parent_node, Node3D *&out_root_node,
int depth, const Vector<VoxMesh> &meshes, float scale, bool p_enable_baked_lighting) {
//
@ -151,8 +149,6 @@ static Error process_scene_node_recursively(const Data &data, int node_id, Node3
return OK;
}
} // namespace zylann::voxel::magica
/*static Error save_stex(const Ref<Image> &p_image, const String &p_to_path,
bool p_mipmaps, int p_texture_flags, bool p_streamable,
bool p_detect_3d, bool p_detect_srgb) {
@ -399,3 +395,5 @@ Error VoxelVoxImporter::import(const String &p_source_file, const String &p_save
return OK;
}
} // namespace zylann::voxel::magica

View File

@ -3,6 +3,8 @@
#include <editor/import/editor_import_plugin.h>
namespace zylann::voxel::magica {
// TODO Rename VoxelVoxSceneImporter
// Imports a vox file as a scene, where the internal scene layout is preserved as nodes
class VoxelVoxImporter : public ResourceImporter {
@ -25,4 +27,6 @@ public:
List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr) override;
};
} // namespace zylann::voxel::magica
#endif // VOX_IMPORTER_H

View File

@ -8,8 +8,7 @@
#include "../../util/profiling.h"
#include "vox_import_funcs.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel::magica {
String VoxelVoxMeshImporter::get_importer_name() const {
return "VoxelVoxMeshImporter";
@ -60,8 +59,6 @@ bool VoxelVoxMeshImporter::get_option_visibility(
return true;
}
namespace zylann::voxel::magica {
struct ForEachModelInstanceArgs {
const Model *model;
// Pivot position, which turns out to be at the center in MagicaVoxel
@ -70,8 +67,7 @@ struct ForEachModelInstanceArgs {
};
template <typename F>
static Error for_each_model_instance_in_scene_graph(
const Data &data, int node_id, Transform3D transform, int depth, F f) {
Error for_each_model_instance_in_scene_graph(const Data &data, int node_id, Transform3D transform, int depth, F f) {
//
ERR_FAIL_COND_V(depth > 10, ERR_INVALID_DATA);
const Node *vox_node = data.get_node(node_id);
@ -110,7 +106,8 @@ static Error for_each_model_instance_in_scene_graph(
return OK;
}
template <typename F> void for_each_model_instance(const Data &vox_data, F f) {
template <typename F>
void for_each_model_instance(const Data &vox_data, F f) {
if (vox_data.get_model_count() == 0) {
return;
}
@ -216,8 +213,6 @@ bool make_single_voxel_grid(
return true;
}
} // namespace zylann::voxel::magica
Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_save_path,
const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files,
Variant *r_metadata) {
@ -228,7 +223,7 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_
ERR_FAIL_INDEX_V(p_pivot_mode, PIVOT_MODES_COUNT, ERR_INVALID_PARAMETER);
magica::Data vox_data;
Data vox_data;
const Error load_err = vox_data.load_from_file(p_source_file);
ERR_FAIL_COND_V(load_err != OK, load_err);
@ -249,7 +244,7 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_
Ref<Mesh> mesh;
std::vector<unsigned int> surface_index_to_material;
{
std::vector<magica::ModelInstance> model_instances;
std::vector<ModelInstance> model_instances;
extract_model_instances(vox_data, model_instances);
// From this point we no longer need vox data so we can free some memory
@ -288,7 +283,7 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_
break;
};
mesh = magica::build_mesh(voxels, **mesher, surface_index_to_material, atlas, p_scale, offset);
mesh = build_mesh(voxels, **mesher, surface_index_to_material, atlas, p_scale, offset);
// Deallocate large temporary memory to free space.
// This is a workaround because VoxelBuffer uses this by default, however it doesn't fit the present use case.
// Eventually we should avoid using this pool here.
@ -367,3 +362,5 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_
return OK;
}
} // namespace zylann::voxel::magica

View File

@ -3,6 +3,8 @@
#include <editor/import/editor_import_plugin.h>
namespace zylann::voxel::magica {
// Imports a vox file as a single mesh, where all contents of the vox scene is merged
class VoxelVoxMeshImporter : public ResourceImporter {
GDCLASS(VoxelVoxMeshImporter, ResourceImporter)
@ -31,4 +33,6 @@ public:
};
};
} // namespace zylann::voxel::magica
#endif // VOX_MESH_IMPORTER_H

View File

@ -6,8 +6,7 @@
#include <core/core_string_names.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
const char *VoxelGeneratorGraph::SIGNAL_NODE_NAME_CHANGED = "node_name_changed";
@ -399,8 +398,6 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span<const WeightOutput> we
}
}
namespace zylann::voxel {
template <typename F, typename Data_T>
void fill_zx_slice(Span<Data_T> channel_data, float sdf_scale, Vector3i rmin, Vector3i rmax, int ry, int x_stride,
const float *src_data, Vector3i buffer_size, F convert_func) {
@ -455,8 +452,6 @@ static void fill_zx_slice(const VoxelGraphRuntime::Buffer &sdf_buffer, VoxelBuff
}
}
} // namespace zylann::voxel
VoxelGenerator::Result VoxelGeneratorGraph::generate_block(VoxelBlockRequest &input) {
std::shared_ptr<Runtime> runtime_ptr;
{
@ -1208,7 +1203,7 @@ static Dictionary get_graph_as_variant_data(const ProgramGraph &graph) {
}
Dictionary VoxelGeneratorGraph::get_graph_as_variant_data() const {
return ::get_graph_as_variant_data(_graph);
return zylann::voxel::get_graph_as_variant_data(_graph);
}
static bool var_to_id(Variant v, uint32_t &out_id, uint32_t min = 0) {
@ -1282,7 +1277,7 @@ static bool load_graph_from_variant_data(ProgramGraph &graph, Dictionary data) {
void VoxelGeneratorGraph::load_graph_from_variant_data(Dictionary data) {
clear();
if (::load_graph_from_variant_data(_graph, data)) {
if (zylann::voxel::load_graph_from_variant_data(_graph, data)) {
register_subresources();
// It's possible to auto-compile on load because `graph_data` is the only property set by the loader,
// which is enough to have all information we need
@ -1673,3 +1668,5 @@ void VoxelGeneratorGraph::_bind_methods() {
#endif
BIND_ENUM_CONSTANT(NODE_TYPE_COUNT);
}
} // namespace zylann::voxel

View File

@ -6,6 +6,8 @@
#include "voxel_graph_runtime.h"
#include <memory>
namespace zylann::voxel {
class VoxelGeneratorGraph : public VoxelGenerator {
GDCLASS(VoxelGeneratorGraph, VoxelGenerator)
public:
@ -76,7 +78,7 @@ public:
// Important: functions editing the graph are NOT thread-safe.
// They are expected to be used by the main thread (editor or game logic).
uint32_t create_node(NodeTypeID type_id, Vector2 position, uint32_t id = zylann::ProgramGraph::NULL_ID);
uint32_t create_node(NodeTypeID type_id, Vector2 position, uint32_t id = ProgramGraph::NULL_ID);
void remove_node(uint32_t node_id);
bool can_connect(
@ -84,9 +86,8 @@ public:
void add_connection(uint32_t src_node_id, uint32_t src_port_index, uint32_t dst_node_id, uint32_t dst_port_index);
void remove_connection(
uint32_t src_node_id, uint32_t src_port_index, uint32_t dst_node_id, uint32_t dst_port_index);
void get_connections(std::vector<zylann::ProgramGraph::Connection> &connections) const;
bool try_get_connection_to(
zylann::ProgramGraph::PortLocation dst, zylann::ProgramGraph::PortLocation &out_src) const;
void get_connections(std::vector<ProgramGraph::Connection> &connections) const;
bool try_get_connection_to(ProgramGraph::PortLocation dst, ProgramGraph::PortLocation &out_src) const;
bool has_node(uint32_t node_id) const;
@ -153,22 +154,22 @@ public:
// Internal
zylann::voxel::VoxelGraphRuntime::CompilationResult compile();
VoxelGraphRuntime::CompilationResult compile();
bool is_good() const;
void generate_set(Span<float> in_x, Span<float> in_y, Span<float> in_z);
// Returns state from the last generator used in the current thread
static const zylann::voxel::VoxelGraphRuntime::State &get_last_state_from_current_thread();
static const VoxelGraphRuntime::State &get_last_state_from_current_thread();
static Span<const int> get_last_execution_map_debug_from_current_thread();
bool try_get_output_port_address(zylann::ProgramGraph::PortLocation port, uint32_t &out_address) const;
bool try_get_output_port_address(ProgramGraph::PortLocation port, uint32_t &out_address) const;
void find_dependencies(uint32_t node_id, std::vector<uint32_t> &out_dependencies) const;
// Debug
zylann::math::Interval debug_analyze_range(Vector3i min_pos, Vector3i max_pos, bool optimize_execution_map) const;
math::Interval debug_analyze_range(Vector3i min_pos, Vector3i max_pos, bool optimize_execution_map) const;
float debug_measure_microseconds_per_voxel(bool singular);
void debug_load_waves_preset();
@ -198,12 +199,12 @@ private:
};
static void gather_indices_and_weights(Span<const WeightOutput> weight_outputs,
const zylann::voxel::VoxelGraphRuntime::State &state, Vector3i rmin, Vector3i rmax, int ry,
zylann::voxel::VoxelBufferInternal &out_voxel_buffer, zylann::FixedArray<uint8_t, 4> spare_indices);
const VoxelGraphRuntime::State &state, Vector3i rmin, Vector3i rmax, int ry,
VoxelBufferInternal &out_voxel_buffer, FixedArray<uint8_t, 4> spare_indices);
static void _bind_methods();
zylann::ProgramGraph _graph;
ProgramGraph _graph;
// This generator performs range analysis using nodes of the graph. Terrain surface can only appear when SDF
// crosses zero within a block. For each generated block, an estimated range of the output is calculated.
// If that range is beyond this threshold (either negatively or positively), then blocks will be given a uniform
@ -228,15 +229,15 @@ private:
// Only compiling and generation methods are thread-safe.
struct Runtime {
zylann::voxel::VoxelGraphRuntime runtime;
VoxelGraphRuntime runtime;
// Indices that are not used in the graph.
// This is used when there are less than 4 texture weight outputs.
zylann::FixedArray<uint8_t, 4> spare_texture_indices;
FixedArray<uint8_t, 4> spare_texture_indices;
// Index to the SDF output
int sdf_output_buffer_index = -1;
zylann::FixedArray<WeightOutput, 16> weight_outputs;
FixedArray<WeightOutput, 16> weight_outputs;
// List of indices to feed queries. The order doesn't matter, can be different from `weight_outputs`.
zylann::FixedArray<unsigned int, 16> weight_output_indices;
FixedArray<unsigned int, 16> weight_output_indices;
unsigned int weight_outputs_count = 0;
};
@ -247,13 +248,15 @@ private:
std::vector<float> x_cache;
std::vector<float> y_cache;
std::vector<float> z_cache;
zylann::voxel::VoxelGraphRuntime::State state;
zylann::voxel::VoxelGraphRuntime::ExecutionMap optimized_execution_map;
VoxelGraphRuntime::State state;
VoxelGraphRuntime::ExecutionMap optimized_execution_map;
};
static thread_local Cache _cache;
};
VARIANT_ENUM_CAST(VoxelGeneratorGraph::NodeTypeID)
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelGeneratorGraph::NodeTypeID)
#endif // VOXEL_GENERATOR_GRAPH_H

View File

@ -1,6 +1,6 @@
#include "voxel_generator_flat.h"
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelGeneratorFlat::VoxelGeneratorFlat() {}
@ -136,3 +136,5 @@ void VoxelGeneratorFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_type", PROPERTY_HINT_RANGE, "0,65536,1"), "set_voxel_type",
"get_voxel_type");
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include "../voxel_generator.h"
namespace zylann::voxel {
class VoxelGeneratorFlat : public VoxelGenerator {
GDCLASS(VoxelGeneratorFlat, VoxelGenerator)
@ -27,7 +29,7 @@ protected:
private:
struct Parameters {
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
int voxel_type = 1;
float height = 0;
float iso_scale = 0.1;
@ -37,4 +39,6 @@ private:
RWLock _parameters_lock;
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_FLAT_H

View File

@ -2,7 +2,7 @@
#include "../../util/fixed_array.h"
#include "../../util/span.h"
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelGeneratorHeightmap::VoxelGeneratorHeightmap() {}
@ -83,3 +83,5 @@ void VoxelGeneratorHeightmap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_range"), "set_height_range", "get_height_range");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "iso_scale"), "set_iso_scale", "get_iso_scale");
}
} // namespace zylann::voxel

View File

@ -5,6 +5,8 @@
#include "../voxel_generator.h"
#include <core/io/image.h>
namespace zylann::voxel {
class VoxelGeneratorHeightmap : public VoxelGenerator {
GDCLASS(VoxelGeneratorHeightmap, VoxelGenerator)
public:
@ -26,7 +28,7 @@ public:
protected:
template <typename Height_F>
Result generate(zylann::voxel::VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
Result generate(VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
Parameters params;
{
RWLockRead rlock(_parameters_lock);
@ -35,7 +37,7 @@ protected:
const int channel = params.channel;
const Vector3i bs = out_buffer.get_size();
const bool use_sdf = channel == zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
const bool use_sdf = channel == VoxelBufferInternal::CHANNEL_SDF;
if (origin.y > get_height_start() + get_height_range()) {
// The bottom of the block is above the highest ground can go (default is air)
@ -111,7 +113,7 @@ private:
};
struct Parameters {
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
int matter_type = 1;
Range range;
float iso_scale = 0.1;
@ -121,4 +123,6 @@ private:
Parameters _parameters;
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_HEIGHTMAP_H

View File

@ -2,8 +2,7 @@
#include "../../util/fixed_array.h"
#include "../../util/span.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
namespace {
@ -95,3 +94,5 @@ void VoxelGeneratorImage::_bind_methods() {
PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_image", "get_image");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blur_enabled"), "set_blur_enabled", "is_blur_enabled");
}
} // namespace zylann::voxel

View File

@ -4,6 +4,8 @@
#include "voxel_generator_heightmap.h"
#include <core/io/image.h>
namespace zylann::voxel {
// Provides infinite tiling heightmap based on an image
class VoxelGeneratorImage : public VoxelGeneratorHeightmap {
GDCLASS(VoxelGeneratorImage, VoxelGeneratorHeightmap)
@ -40,4 +42,6 @@ private:
RWLock _parameters_lock;
};
} // namespace zylann::voxel
#endif // HEADER_VOXEL_GENERATOR_IMAGE

View File

@ -2,7 +2,7 @@
#include <core/config/engine.h>
#include <core/core_string_names.h>
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelGeneratorNoise::VoxelGeneratorNoise() {}
@ -251,3 +251,5 @@ void VoxelGeneratorNoise::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_start"), "set_height_start", "get_height_start");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_range"), "set_height_range", "get_height_range");
}
} // namespace zylann::voxel

View File

@ -4,6 +4,8 @@
#include "../voxel_generator.h"
#include <modules/opensimplex/open_simplex_noise.h>
namespace zylann::voxel {
class VoxelGeneratorNoise : public VoxelGenerator {
GDCLASS(VoxelGeneratorNoise, VoxelGenerator)
@ -35,7 +37,7 @@ private:
Ref<OpenSimplexNoise> _noise;
struct Parameters {
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
Ref<OpenSimplexNoise> noise;
float height_start = 0;
float height_range = 300;
@ -45,4 +47,6 @@ private:
RWLock _parameters_lock;
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_NOISE_H

View File

@ -2,7 +2,7 @@
#include <core/config/engine.h>
#include <core/core_string_names.h>
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelGeneratorNoise2D::VoxelGeneratorNoise2D() {}
@ -117,3 +117,5 @@ void VoxelGeneratorNoise2D::_bind_methods() {
ADD_PROPERTY(
PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
}
} // namespace zylann::voxel

View File

@ -4,6 +4,8 @@
#include "voxel_generator_heightmap.h"
#include <modules/opensimplex/open_simplex_noise.h>
namespace zylann::voxel {
class VoxelGeneratorNoise2D : public VoxelGeneratorHeightmap {
GDCLASS(VoxelGeneratorNoise2D, VoxelGeneratorHeightmap)
@ -38,4 +40,6 @@ private:
RWLock _parameters_lock;
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_NOISE_2D_H

View File

@ -3,6 +3,8 @@
#include "voxel_generator_heightmap.h"
namespace zylann::voxel {
class VoxelGeneratorWaves : public VoxelGeneratorHeightmap {
GDCLASS(VoxelGeneratorWaves, VoxelGeneratorHeightmap)
@ -33,4 +35,6 @@ private:
RWLock _parameters_lock;
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_WAVES_H

View File

@ -1,7 +1,7 @@
#include "voxel_generator.h"
#include "../constants/voxel_string_names.h"
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelGenerator::VoxelGenerator() {}
@ -39,3 +39,5 @@ void VoxelGenerator::_bind_methods() {
ClassDB::bind_method(
D_METHOD("generate_block", "out_buffer", "origin_in_voxels", "lod"), &VoxelGenerator::_b_generate_block);
}
} // namespace zylann::voxel

View File

@ -4,6 +4,8 @@
#include "../streams/voxel_block_request.h"
#include <core/io/resource.h>
namespace zylann::voxel {
union VoxelSingleValue {
uint64_t i;
float f;
@ -27,7 +29,9 @@ public:
virtual Result generate_block(VoxelBlockRequest &input);
// TODO Single sample
virtual bool supports_single_generation() const { return false; }
virtual bool supports_single_generation() const {
return false;
}
// TODO Not sure if it's a good API regarding performance
virtual VoxelSingleValue generate_single(Vector3i pos, unsigned int channel);
@ -46,4 +50,6 @@ protected:
void _b_generate_block(Ref<VoxelBuffer> out_buffer, Vector3 origin_in_voxels, int lod);
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_H

View File

@ -2,6 +2,8 @@
#include "../constants/voxel_string_names.h"
#include "../util/godot/funcs.h"
namespace zylann::voxel {
VoxelGeneratorScript::VoxelGeneratorScript() {}
VoxelGenerator::Result VoxelGeneratorScript::generate_block(VoxelBlockRequest &input) {
@ -48,3 +50,5 @@ void VoxelGeneratorScript::_bind_methods() {
// BIND_VMETHOD(MethodInfo(Variant::INT, "_get_used_channels_mask"));
}
} // namespace zylann::voxel

View File

@ -5,6 +5,8 @@
#include <core/object/script_language.h> // needed for GDVIRTUAL macro
#include <core/object/gdvirtual.gen.inc> // Also needed for GDVIRTUAL macro...
namespace zylann::voxel {
// Generator based on a script, like GDScript, C# or NativeScript.
// The script is expected to properly handle multithreading.
class VoxelGeneratorScript : public VoxelGenerator {
@ -23,4 +25,6 @@ private:
static void _bind_methods();
};
} // namespace zylann::voxel
#endif // VOXEL_GENERATOR_SCRIPT_H

View File

@ -5,8 +5,7 @@
#define STRLEN(x) (sizeof(x) / sizeof(x[0]))
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
Voxel::Voxel() :
_id(-1), _material_id(0), _transparency_index(0), _color(1.f, 1.f, 1.f), _geometry_type(GEOMETRY_NONE) {}
@ -474,6 +473,27 @@ void Voxel::bake(BakedData &baked_data, int p_atlas_size, bool bake_tangents) {
_empty = baked_data.empty;
}
Array Voxel::_b_get_collision_aabbs() const {
Array array;
array.resize(_collision_aabbs.size());
for (size_t i = 0; i < _collision_aabbs.size(); ++i) {
array[i] = _collision_aabbs[i];
}
return array;
}
void Voxel::_b_set_collision_aabbs(Array array) {
for (int i = 0; i < array.size(); ++i) {
const Variant v = array[i];
ERR_FAIL_COND(v.get_type() != Variant::AABB);
}
_collision_aabbs.resize(array.size());
for (int i = 0; i < array.size(); ++i) {
const AABB aabb = array[i];
_collision_aabbs[i] = aabb;
}
}
void Voxel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_voxel_name", "name"), &Voxel::set_voxel_name);
ClassDB::bind_method(D_METHOD("get_voxel_name"), &Voxel::get_voxel_name);
@ -542,23 +562,4 @@ void Voxel::_bind_methods() {
BIND_ENUM_CONSTANT(SIDE_COUNT);
}
Array Voxel::_b_get_collision_aabbs() const {
Array array;
array.resize(_collision_aabbs.size());
for (size_t i = 0; i < _collision_aabbs.size(); ++i) {
array[i] = _collision_aabbs[i];
}
return array;
}
void Voxel::_b_set_collision_aabbs(Array array) {
for (int i = 0; i < array.size(); ++i) {
const Variant v = array[i];
ERR_FAIL_COND(v.get_type() != Variant::AABB);
}
_collision_aabbs.resize(array.size());
for (int i = 0; i < array.size(); ++i) {
const AABB aabb = array[i];
_collision_aabbs[i] = aabb;
}
}
} // namespace zylann::voxel

View File

@ -7,6 +7,8 @@
#include <scene/resources/mesh.h>
#include <vector>
namespace zylann::voxel {
class VoxelLibrary;
// TODO Rename VoxelBlockyLibraryItem?
@ -34,12 +36,12 @@ public:
// Model sides:
// They are separated because this way we can occlude them easily.
// Due to these defining cube side triangles, normals are known already.
zylann::FixedArray<std::vector<Vector3>, zylann::voxel::Cube::SIDE_COUNT> side_positions;
zylann::FixedArray<std::vector<Vector2>, zylann::voxel::Cube::SIDE_COUNT> side_uvs;
zylann::FixedArray<std::vector<int>, zylann::voxel::Cube::SIDE_COUNT> side_indices;
zylann::FixedArray<std::vector<float>, zylann::voxel::Cube::SIDE_COUNT> side_tangents;
FixedArray<std::vector<Vector3>, Cube::SIDE_COUNT> side_positions;
FixedArray<std::vector<Vector2>, Cube::SIDE_COUNT> side_uvs;
FixedArray<std::vector<int>, Cube::SIDE_COUNT> side_indices;
FixedArray<std::vector<float>, Cube::SIDE_COUNT> side_tangents;
zylann::FixedArray<uint32_t, zylann::voxel::Cube::SIDE_COUNT> side_pattern_indices;
FixedArray<uint32_t, Cube::SIDE_COUNT> side_pattern_indices;
void clear() {
positions.clear();
@ -48,7 +50,7 @@ public:
indices.clear();
tangents.clear();
for (int side = 0; side < zylann::voxel::Cube::SIDE_COUNT; ++side) {
for (int side = 0; side < Cube::SIDE_COUNT; ++side) {
side_positions[side].clear();
side_uvs[side].clear();
side_indices[side].clear();
@ -73,13 +75,13 @@ public:
Voxel();
enum Side {
SIDE_NEGATIVE_X = zylann::voxel::Cube::SIDE_NEGATIVE_X,
SIDE_POSITIVE_X = zylann::voxel::Cube::SIDE_POSITIVE_X,
SIDE_NEGATIVE_Y = zylann::voxel::Cube::SIDE_NEGATIVE_Y,
SIDE_POSITIVE_Y = zylann::voxel::Cube::SIDE_POSITIVE_Y,
SIDE_NEGATIVE_Z = zylann::voxel::Cube::SIDE_NEGATIVE_Z,
SIDE_POSITIVE_Z = zylann::voxel::Cube::SIDE_POSITIVE_Z,
SIDE_COUNT = zylann::voxel::Cube::SIDE_COUNT
SIDE_NEGATIVE_X = Cube::SIDE_NEGATIVE_X,
SIDE_POSITIVE_X = Cube::SIDE_POSITIVE_X,
SIDE_NEGATIVE_Y = Cube::SIDE_NEGATIVE_Y,
SIDE_POSITIVE_Y = Cube::SIDE_POSITIVE_Y,
SIDE_NEGATIVE_Z = Cube::SIDE_NEGATIVE_Z,
SIDE_POSITIVE_Z = Cube::SIDE_POSITIVE_Z,
SIDE_COUNT = Cube::SIDE_COUNT
};
// Properties
@ -192,7 +194,7 @@ private:
Color _color;
GeometryType _geometry_type;
zylann::FixedArray<Vector2, zylann::voxel::Cube::SIDE_COUNT> _cube_tiles;
FixedArray<Vector2, Cube::SIDE_COUNT> _cube_tiles;
Ref<Mesh> _custom_mesh;
std::vector<AABB> _collision_aabbs;
bool _random_tickable = false;
@ -200,7 +202,9 @@ private:
uint32_t _collision_mask = 1;
};
VARIANT_ENUM_CAST(Voxel::GeometryType)
VARIANT_ENUM_CAST(Voxel::Side)
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::Voxel::GeometryType)
VARIANT_ENUM_CAST(zylann::voxel::Voxel::Side)
#endif // VOXEL_TYPE_H

View File

@ -6,8 +6,7 @@
#include <bitset>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelLibrary::VoxelLibrary() {}
@ -431,3 +430,5 @@ Ref<Voxel> VoxelLibrary::_b_get_voxel_by_name(StringName name) {
ERR_FAIL_COND_V(id == -1, Ref<Voxel>());
return _voxel_types[id];
}
} // namespace zylann::voxel

View File

@ -5,6 +5,8 @@
#include "voxel.h"
#include <core/object/ref_counted.h>
namespace zylann::voxel {
// TODO Rename VoxelBlockyLibrary
// Stores a list of models that can be used with VoxelMesherBlocky
@ -19,7 +21,7 @@ public:
struct BakedData {
// 2D array: { X : pattern A, Y : pattern B } => Does A occlude B
// Where index is X + Y * pattern count
zylann::DynamicBitset side_pattern_culling;
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;
@ -107,4 +109,6 @@ private:
BakedData _baked_data;
};
} // namespace zylann::voxel
#endif // VOXEL_LIBRARY_H

View File

@ -330,10 +330,7 @@ void generate_blocky_mesh(
}
}
} // namespace zylann::voxel
using namespace zylann;
using namespace voxel;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
thread_local VoxelMesherBlocky::Cache VoxelMesherBlocky::_cache;
@ -554,3 +551,5 @@ void VoxelMesherBlocky::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "occlusion_darkness", PROPERTY_HINT_RANGE, "0,1,0.01"),
"set_occlusion_darkness", "get_occlusion_darkness");
}
} // namespace zylann::voxel

View File

@ -7,6 +7,8 @@
#include <scene/resources/mesh.h>
#include <vector>
namespace zylann::voxel {
// TODO Rename VoxelMesherModelBatch
// Interprets voxel values as indexes to models in a VoxelLibrary, and batches them together.
@ -70,7 +72,7 @@ private:
};
struct Cache {
zylann::FixedArray<Arrays, MAX_MATERIALS> arrays_per_material;
FixedArray<Arrays, MAX_MATERIALS> arrays_per_material;
};
// Parameters
@ -81,4 +83,6 @@ private:
static thread_local Cache _cache;
};
} // namespace zylann::voxel
#endif // VOXEL_MESHER_BLOCKY_H

View File

@ -1,6 +1,6 @@
#include "voxel_color_palette.h"
using namespace zylann;
namespace zylann::voxel {
VoxelColorPalette::VoxelColorPalette() {
// Default palette
@ -79,3 +79,5 @@ void VoxelColorPalette::_bind_methods() {
BIND_CONSTANT(MAX_COLORS);
}
} // namespace zylann::voxel

View File

@ -5,6 +5,8 @@
#include "../../util/math/color8.h"
#include <core/io/resource.h>
namespace zylann::voxel {
// Associates small numbers to colors, so colored voxels can be specified using less memory.
class VoxelColorPalette : public Resource {
GDCLASS(VoxelColorPalette, Resource)
@ -23,11 +25,11 @@ public:
// Internal
inline void set_color8(uint8_t i, zylann::Color8 c) {
inline void set_color8(uint8_t i, Color8 c) {
_colors[i] = c;
}
inline zylann::Color8 get_color8(uint8_t i) const {
inline Color8 get_color8(uint8_t i) const {
return _colors[i];
}
@ -37,7 +39,9 @@ private:
static void _bind_methods();
zylann::FixedArray<zylann::Color8, MAX_COLORS> _colors;
FixedArray<Color8, MAX_COLORS> _colors;
};
} // namespace zylann::voxel
#endif // VOXEL_COLOR_PALETTE_H

View File

@ -694,8 +694,6 @@ Ref<Image> make_greedy_atlas(
return image;
}
} // namespace zylann::voxel
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
thread_local VoxelMesherCubes::Cache VoxelMesherCubes::_cache;
@ -707,9 +705,6 @@ VoxelMesherCubes::VoxelMesherCubes() {
VoxelMesherCubes::~VoxelMesherCubes() {}
void VoxelMesherCubes::build(VoxelMesher::Output &output, const VoxelMesher::Input &input) {
using namespace zylann;
using namespace voxel;
VOXEL_PROFILE_SCOPE();
const int channel = VoxelBufferInternal::CHANNEL_COLOR;
Cache &cache = _cache;
@ -1032,3 +1027,5 @@ void VoxelMesherCubes::_bind_methods() {
BIND_ENUM_CONSTANT(COLOR_MESHER_PALETTE);
BIND_ENUM_CONSTANT(COLOR_SHADER_PALETTE);
}
} // namespace zylann::voxel

View File

@ -5,6 +5,8 @@
#include "voxel_color_palette.h"
#include <vector>
namespace zylann::voxel {
// A super simple mesher only producing colored cubes
class VoxelMesherCubes : public VoxelMesher {
GDCLASS(VoxelMesherCubes, VoxelMesher)
@ -83,7 +85,7 @@ public:
unsigned int size_y;
unsigned int surface_index;
};
std::vector<zylann::Color8> colors;
std::vector<Color8> colors;
std::vector<ImageInfo> images;
void clear() {
@ -104,7 +106,7 @@ private:
};
struct Cache {
zylann::FixedArray<Arrays, MATERIAL_COUNT> arrays_per_material;
FixedArray<Arrays, MATERIAL_COUNT> arrays_per_material;
std::vector<uint8_t> mask_memory_pool;
GreedyAtlasData greedy_atlas_data;
};
@ -117,7 +119,9 @@ private:
static thread_local Cache _cache;
};
VARIANT_ENUM_CAST(VoxelMesherCubes::ColorMode);
VARIANT_ENUM_CAST(VoxelMesherCubes::Materials);
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherCubes::ColorMode);
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherCubes::Materials);
#endif // VOXEL_MESHER_CUBES_H

View File

@ -1338,6 +1338,8 @@ void polygonize_volume_directly(const VoxelBufferInternal &voxels, Vector3i min,
} //namespace zylann::voxel::dmc
namespace zylann::voxel {
#define BUILD_OCTREE_BOTTOM_UP
thread_local VoxelMesherDMC::Cache VoxelMesherDMC::_cache;
@ -1585,3 +1587,5 @@ void VoxelMesherDMC::_bind_methods() {
BIND_ENUM_CONSTANT(SEAM_NONE);
BIND_ENUM_CONSTANT(SEAM_MARCHING_SQUARE_SKIRTS);
}
} // namespace zylann::voxel

View File

@ -60,6 +60,8 @@ struct DualGrid {
} // namespace zylann::voxel::dmc
namespace zylann::voxel {
// Mesher extending Marching Cubes using a dual grid.
class VoxelMesherDMC : public VoxelMesher {
GDCLASS(VoxelMesherDMC, VoxelMesher)
@ -120,9 +122,9 @@ private:
};
struct Cache {
zylann::voxel::dmc::MeshBuilder mesh_builder;
zylann::voxel::dmc::DualGrid dual_grid;
zylann::voxel::dmc::OctreeNodePool octree_node_pool;
dmc::MeshBuilder mesh_builder;
dmc::DualGrid dual_grid;
dmc::OctreeNodePool octree_node_pool;
};
// Parameters
@ -142,8 +144,10 @@ private:
Stats _stats;
};
VARIANT_ENUM_CAST(VoxelMesherDMC::SimplifyMode)
VARIANT_ENUM_CAST(VoxelMesherDMC::MeshMode)
VARIANT_ENUM_CAST(VoxelMesherDMC::SeamMode)
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherDMC::SimplifyMode)
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherDMC::MeshMode)
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherDMC::SeamMode)
#endif // VOXEL_MESHER_DMC_H

View File

@ -5,8 +5,7 @@
#include "../../util/profiling.h"
#include "transvoxel_tables.cpp"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
VoxelMesherTransvoxel::VoxelMesherTransvoxel() {
set_padding(transvoxel::MIN_PADDING, transvoxel::MAX_PADDING);
@ -306,3 +305,5 @@ void VoxelMesherTransvoxel::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURES_NONE);
BIND_ENUM_CONSTANT(TEXTURES_BLEND_4_OVER_16);
}
} // namespace zylann::voxel

View File

@ -6,13 +6,15 @@
class ArrayMesh;
namespace zylann::voxel {
class VoxelMesherTransvoxel : public VoxelMesher {
GDCLASS(VoxelMesherTransvoxel, VoxelMesher)
public:
enum TexturingMode {
TEXTURES_NONE = zylann::voxel::transvoxel::TEXTURES_NONE,
TEXTURES_BLEND_4_OVER_16 = zylann::voxel::transvoxel::TEXTURES_BLEND_4_OVER_16
TEXTURES_NONE = transvoxel::TEXTURES_NONE,
TEXTURES_BLEND_4_OVER_16 = transvoxel::TEXTURES_BLEND_4_OVER_16
};
VoxelMesherTransvoxel();
@ -40,7 +42,7 @@ protected:
static void _bind_methods();
private:
void fill_surface_arrays(Array &arrays, const zylann::voxel::transvoxel::MeshArrays &src);
void fill_surface_arrays(Array &arrays, const transvoxel::MeshArrays &src);
TexturingMode _texture_mode = TEXTURES_NONE;
@ -53,6 +55,8 @@ private:
MeshOptimizationParams _mesh_optimization_params;
};
VARIANT_ENUM_CAST(VoxelMesherTransvoxel::TexturingMode);
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelMesherTransvoxel::TexturingMode);
#endif // VOXEL_MESHER_TRANSVOXEL_H

View File

@ -2,7 +2,7 @@
#include "../storage/voxel_buffer.h"
#include "../util/godot/funcs.h"
using namespace zylann;
namespace zylann::voxel {
Ref<Mesh> VoxelMesher::build_mesh(Ref<VoxelBuffer> voxels, Array materials) {
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
@ -66,3 +66,5 @@ void VoxelMesher::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_minimum_padding"), &VoxelMesher::get_minimum_padding);
ClassDB::bind_method(D_METHOD("get_maximum_padding"), &VoxelMesher::get_maximum_padding);
}
} // namespace zylann::voxel

View File

@ -5,24 +5,23 @@
#include "../util/fixed_array.h"
#include <scene/resources/mesh.h>
class VoxelBuffer;
namespace zylann::voxel {
class VoxelBuffer;
class VoxelBufferInternal;
}
class VoxelMesher : public Resource {
GDCLASS(VoxelMesher, Resource)
public:
struct Input {
const zylann::voxel::VoxelBufferInternal &voxels;
const VoxelBufferInternal &voxels;
int lod; // = 0; // Not initialized because it confused GCC
};
struct Output {
// Each surface correspond to a different material
Vector<Array> surfaces;
zylann::FixedArray<Vector<Array>, zylann::voxel::Cube::SIDE_COUNT> transition_surfaces;
FixedArray<Vector<Array>, Cube::SIDE_COUNT> transition_surfaces;
Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES;
unsigned int mesh_flags = 0;
Ref<Image> atlas_image;
@ -68,4 +67,6 @@ private:
unsigned int _maximum_padding = 0;
};
} // namespace zylann::voxel
#endif // VOXEL_MESHER_H

View File

@ -160,7 +160,7 @@ void register_voxel_types() {
EditorPlugins::add_by_type<VoxelTerrainEditorPlugin>();
EditorPlugins::add_by_type<VoxelInstanceLibraryEditorPlugin>();
EditorPlugins::add_by_type<FastNoiseLiteEditorPlugin>();
EditorPlugins::add_by_type<VoxEditorPlugin>();
EditorPlugins::add_by_type<magica::VoxEditorPlugin>();
EditorPlugins::add_by_type<VoxelInstancerEditorPlugin>();
#ifdef VOXEL_ENABLE_FAST_NOISE_2
EditorPlugins::add_by_type<FastNoise2EditorPlugin>();

View File

@ -12,8 +12,6 @@
#include <memory>
class VoxelNode;
namespace zylann {
class AsyncDependencyTracker;
}

View File

@ -5,9 +5,9 @@
// Needed for doing `Node *root = SceneTree::get_root()`, Window* is forward-declared
#include <scene/main/window.h>
namespace {
namespace zylann::voxel {
bool g_updater_created = false;
}
VoxelServerUpdater::VoxelServerUpdater() {
PRINT_VERBOSE("Creating VoxelServerUpdater");
@ -53,3 +53,5 @@ void VoxelServerUpdater::_notification(int p_what) {
break;
}
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include <scene/main/node.h>
namespace zylann::voxel {
// TODO Hack to make VoxelServer update... need ways to integrate callbacks from main loop!
class VoxelServerUpdater : public Node {
GDCLASS(VoxelServerUpdater, Node)
@ -17,4 +19,6 @@ private:
VoxelServerUpdater();
};
} // namespace zylann::voxel
#endif // VOXEL_SERVER_UPDATER_H

View File

@ -4,8 +4,7 @@
#include <core/io/image.h>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
const char *VoxelBuffer::CHANNEL_ID_HINT_STRING = "Type,Sdf,Color,Indices,Weights,Data5,Data6,Data7";
@ -196,3 +195,5 @@ void VoxelBuffer::_bind_methods() {
BIND_CONSTANT(MAX_SIZE);
}
} // namespace zylann::voxel

View File

@ -4,9 +4,12 @@
#include "voxel_buffer_internal.h"
#include <memory>
class VoxelTool;
class Image;
namespace zylann::voxel {
class VoxelTool;
// TODO I wish I could call the original class `VoxelBuffer` and expose this other one with that name.
// Godot doesn't seem to allow doing that. So the original class had to be named `VoxelBufferInternal`...
@ -18,33 +21,33 @@ class VoxelBuffer : public RefCounted {
public:
enum ChannelId {
CHANNEL_TYPE = zylann::voxel::VoxelBufferInternal::CHANNEL_TYPE,
CHANNEL_SDF = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF,
CHANNEL_COLOR = zylann::voxel::VoxelBufferInternal::CHANNEL_COLOR,
CHANNEL_INDICES = zylann::voxel::VoxelBufferInternal::CHANNEL_INDICES,
CHANNEL_WEIGHTS = zylann::voxel::VoxelBufferInternal::CHANNEL_WEIGHTS,
CHANNEL_DATA5 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA5,
CHANNEL_DATA6 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA6,
CHANNEL_DATA7 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA7,
MAX_CHANNELS = zylann::voxel::VoxelBufferInternal::MAX_CHANNELS,
CHANNEL_TYPE = VoxelBufferInternal::CHANNEL_TYPE,
CHANNEL_SDF = VoxelBufferInternal::CHANNEL_SDF,
CHANNEL_COLOR = VoxelBufferInternal::CHANNEL_COLOR,
CHANNEL_INDICES = VoxelBufferInternal::CHANNEL_INDICES,
CHANNEL_WEIGHTS = VoxelBufferInternal::CHANNEL_WEIGHTS,
CHANNEL_DATA5 = VoxelBufferInternal::CHANNEL_DATA5,
CHANNEL_DATA6 = VoxelBufferInternal::CHANNEL_DATA6,
CHANNEL_DATA7 = VoxelBufferInternal::CHANNEL_DATA7,
MAX_CHANNELS = VoxelBufferInternal::MAX_CHANNELS,
};
// TODO use C++17 inline to initialize right here...
static const char *CHANNEL_ID_HINT_STRING;
enum Compression {
COMPRESSION_NONE = zylann::voxel::VoxelBufferInternal::COMPRESSION_NONE,
COMPRESSION_UNIFORM = zylann::voxel::VoxelBufferInternal::COMPRESSION_UNIFORM,
COMPRESSION_NONE = VoxelBufferInternal::COMPRESSION_NONE,
COMPRESSION_UNIFORM = VoxelBufferInternal::COMPRESSION_UNIFORM,
//COMPRESSION_RLE,
COMPRESSION_COUNT = zylann::voxel::VoxelBufferInternal::COMPRESSION_COUNT
COMPRESSION_COUNT = VoxelBufferInternal::COMPRESSION_COUNT
};
enum Depth {
DEPTH_8_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_8_BIT,
DEPTH_16_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_16_BIT,
DEPTH_32_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_32_BIT,
DEPTH_64_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_64_BIT,
DEPTH_COUNT = zylann::voxel::VoxelBufferInternal::DEPTH_COUNT
DEPTH_8_BIT = VoxelBufferInternal::DEPTH_8_BIT,
DEPTH_16_BIT = VoxelBufferInternal::DEPTH_16_BIT,
DEPTH_32_BIT = VoxelBufferInternal::DEPTH_32_BIT,
DEPTH_64_BIT = VoxelBufferInternal::DEPTH_64_BIT,
DEPTH_COUNT = VoxelBufferInternal::DEPTH_COUNT
};
// Limit was made explicit for serialization reasons, and also because there must be a reasonable one
@ -53,18 +56,18 @@ public:
// Constructs a new buffer
VoxelBuffer();
// Reference an existing buffer
VoxelBuffer(std::shared_ptr<zylann::voxel::VoxelBufferInternal> &other);
VoxelBuffer(std::shared_ptr<VoxelBufferInternal> &other);
~VoxelBuffer();
inline const zylann::voxel::VoxelBufferInternal &get_buffer() const {
inline const VoxelBufferInternal &get_buffer() const {
#ifdef DEBUG_ENABLED
CRASH_COND(_buffer == nullptr);
#endif
return *_buffer;
}
inline zylann::voxel::VoxelBufferInternal &get_buffer() {
inline VoxelBufferInternal &get_buffer() {
#ifdef DEBUG_ENABLED
CRASH_COND(_buffer == nullptr);
#endif
@ -163,11 +166,13 @@ private:
static void _bind_methods();
// Not sure yet if we'll really need shared_ptr or just no pointer
std::shared_ptr<zylann::voxel::VoxelBufferInternal> _buffer;
std::shared_ptr<VoxelBufferInternal> _buffer;
};
VARIANT_ENUM_CAST(VoxelBuffer::ChannelId)
VARIANT_ENUM_CAST(VoxelBuffer::Depth)
VARIANT_ENUM_CAST(VoxelBuffer::Compression)
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelBuffer::ChannelId)
VARIANT_ENUM_CAST(zylann::voxel::VoxelBuffer::Depth)
VARIANT_ENUM_CAST(zylann::voxel::VoxelBuffer::Compression)
#endif // VOXEL_BUFFER_H

View File

@ -12,11 +12,12 @@
#include <core/templates/vector.h>
#include <limits>
class VoxelTool;
class Image;
namespace zylann::voxel {
class VoxelTool;
// TODO This class is still suffixed "Internal" to avoid conflict with the registered Godot class.
// Even though the other class is not namespaced yet, it is unsure if it will remain that way after the future port
// to GDExtension

View File

@ -8,10 +8,10 @@
#include <scene/main/node.h>
#include <unordered_map>
class VoxelGenerator;
namespace zylann::voxel {
class VoxelGenerator;
// Infinite voxel storage by means of octants like Gridmap, within a constant LOD.
// Convenience functions to access VoxelBuffers internally will lock them to protect against multithreaded access.
// However, the map itself is not thread-safe.

View File

@ -84,8 +84,8 @@ public:
bool set_format(const RegionFormat &format);
const RegionFormat &get_format() const;
Error load_block(Vector3i position, VoxelBufferInternal &out_block, zylann::voxel::BlockSerializer &serializer);
Error save_block(Vector3i position, VoxelBufferInternal &block, zylann::voxel::BlockSerializer &serializer);
Error load_block(Vector3i position, VoxelBufferInternal &out_block, BlockSerializer &serializer);
Error save_block(Vector3i position, VoxelBufferInternal &block, BlockSerializer &serializer);
unsigned int get_header_block_count() const;
bool has_block(Vector3i position) const;

View File

@ -8,8 +8,7 @@
#include <core/os/time.h>
#include <algorithm>
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
namespace {
const uint8_t FORMAT_VERSION = 3;
@ -195,7 +194,7 @@ void VoxelStreamRegionFiles::_immerge_block(VoxelBufferInternal &voxel_buffer, V
if (load_res != FILE_OK && load_res != FILE_CANT_OPEN) {
// The file is present but there is a problem with it
String meta_path = _directory_path.plus_file(META_FILE_NAME);
ERR_PRINT(String("Could not read {0}: error {1}").format(varray(meta_path, ::to_string(load_res))));
ERR_PRINT(String("Could not read {0}: error {1}").format(varray(meta_path, zylann::to_string(load_res))));
return;
}
}
@ -896,3 +895,5 @@ void VoxelStreamRegionFiles::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "block_size_po2"), "set_block_size_po2", "get_region_size_po2");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sector_size"), "set_sector_size", "get_sector_size");
}
} // namespace zylann::voxel

View File

@ -9,6 +9,8 @@
class FileAccess;
namespace zylann::voxel {
// TODO Rename VoxelStreamRegionForest
// Loads and saves blocks to the filesystem, in multiple region files indexed by world position, under a directory.
@ -24,8 +26,8 @@ public:
VoxelStreamRegionFiles();
~VoxelStreamRegionFiles();
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
void emerge_blocks(Span<VoxelBlockRequest> p_blocks, Vector<Result> &out_results) override;
void immerge_blocks(Span<VoxelBlockRequest> p_blocks) override;
@ -64,11 +66,11 @@ private:
EMERGE_FAILED
};
EmergeResult _emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
void _immerge_block(zylann::voxel::VoxelBufferInternal &voxel_buffer, Vector3i origin_in_voxels, int lod);
EmergeResult _emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
void _immerge_block(VoxelBufferInternal &voxel_buffer, Vector3i origin_in_voxels, int lod);
zylann::FileResult save_meta();
zylann::FileResult load_meta();
FileResult save_meta();
FileResult load_meta();
Vector3i get_block_position_from_voxels(const Vector3i &origin_in_voxels) const;
Vector3i get_region_position_from_blocks(const Vector3i &block_position) const;
void close_all_regions();
@ -83,8 +85,7 @@ private:
uint8_t lod_count = 0;
uint8_t block_size_po2 = 0; // How many voxels in a cubic block
uint8_t region_size_po2 = 0; // How many blocks in one cubic region
zylann::FixedArray<zylann::voxel::VoxelBufferInternal::Depth, zylann::voxel::VoxelBufferInternal::MAX_CHANNELS>
channel_depths;
FixedArray<VoxelBufferInternal::Depth, VoxelBufferInternal::MAX_CHANNELS> channel_depths;
uint32_t sector_size = 0; // Blocks are stored at offsets multiple of that size
};
@ -110,7 +111,7 @@ private:
}
};
static thread_local zylann::voxel::BlockSerializer _block_serializer;
static thread_local BlockSerializer _block_serializer;
// TODO This is not thread-friendly.
// `VoxelRegionFile` is not thread-safe so we have to limit the usage to one thread at once, blocking the others.
@ -120,7 +121,7 @@ private:
Vector3i position;
int lod = 0;
bool file_exists = false;
zylann::voxel::RegionFile region;
RegionFile region;
uint64_t last_opened = 0;
//uint64_t last_accessed;
};
@ -136,4 +137,6 @@ private:
Mutex _mutex;
};
} // namespace zylann::voxel
#endif // VOXEL_STREAM_REGION_H

View File

@ -572,13 +572,8 @@ void VoxelStreamSQLiteInternal::save_meta(Meta meta) {
}
}
} // namespace zylann::voxel
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using namespace zylann;
using namespace voxel;
thread_local BlockSerializer VoxelStreamSQLite::_voxel_block_serializer;
thread_local std::vector<uint8_t> VoxelStreamSQLite::_temp_block_data;
thread_local std::vector<uint8_t> VoxelStreamSQLite::_temp_compressed_block_data;
@ -986,3 +981,5 @@ void VoxelStreamSQLite::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "database_path", PROPERTY_HINT_FILE), "set_database_path",
"get_database_path");
}
} // namespace zylann::voxel

View File

@ -8,8 +8,8 @@
#include <vector>
namespace zylann::voxel {
class VoxelStreamSQLiteInternal;
}
// Saves voxel data into a single SQLite database file.
class VoxelStreamSQLite : public VoxelStream {
@ -23,8 +23,8 @@ public:
void set_database_path(String path);
String get_database_path() const;
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
void emerge_blocks(Span<VoxelBlockRequest> p_blocks, Vector<Result> &out_results) override;
void immerge_blocks(Span<VoxelBlockRequest> p_blocks) override;
@ -57,21 +57,23 @@ private:
// Because of this, in our use case, it might be simpler to just leave SQLite in thread-safe mode,
// and synchronize ourselves.
zylann::voxel::VoxelStreamSQLiteInternal *get_connection();
void recycle_connection(zylann::voxel::VoxelStreamSQLiteInternal *con);
void flush_cache(zylann::voxel::VoxelStreamSQLiteInternal *con);
VoxelStreamSQLiteInternal *get_connection();
void recycle_connection(VoxelStreamSQLiteInternal *con);
void flush_cache(VoxelStreamSQLiteInternal *con);
static void _bind_methods();
String _connection_path;
std::vector<zylann::voxel::VoxelStreamSQLiteInternal *> _connection_pool;
std::vector<VoxelStreamSQLiteInternal *> _connection_pool;
Mutex _connection_mutex;
zylann::voxel::VoxelStreamCache _cache;
VoxelStreamCache _cache;
// TODO I should consider specialized memory allocators
static thread_local zylann::voxel::BlockSerializer _voxel_block_serializer;
static thread_local BlockSerializer _voxel_block_serializer;
static thread_local std::vector<uint8_t> _temp_block_data;
static thread_local std::vector<uint8_t> _temp_compressed_block_data;
};
} // namespace zylann::voxel
#endif // VOXEL_STREAM_SQLITE_H

View File

@ -3,8 +3,7 @@
#include "../storage/voxel_buffer.h"
#include "vox_data.h"
using namespace zylann;
using namespace voxel;
namespace zylann::voxel {
Error VoxelVoxLoader::load_from_file(String fpath, Ref<VoxelBuffer> p_voxels, Ref<VoxelColorPalette> palette) {
ERR_FAIL_COND_V(p_voxels.is_null(), ERR_INVALID_PARAMETER);
@ -76,3 +75,5 @@ Error VoxelVoxLoader::load_from_file(String fpath, Ref<VoxelBuffer> p_voxels, Re
void VoxelVoxLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_from_file", "fpath", "voxels"), &VoxelVoxLoader::load_from_file);
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include <core/object/ref_counted.h>
namespace zylann::voxel {
class VoxelBuffer;
class VoxelColorPalette;
@ -19,4 +21,6 @@ private:
static void _bind_methods();
};
} // namespace zylann::voxel
#endif // VOX_LOADER_H

View File

@ -6,9 +6,11 @@
#include "instance_data.h"
#include <memory>
namespace zylann::voxel {
// TODO Rename VoxelStreamBlockRequest
struct VoxelBlockRequest {
zylann::voxel::VoxelBufferInternal &voxel_buffer;
VoxelBufferInternal &voxel_buffer;
Vector3i origin_in_voxels;
int lod;
};
@ -19,4 +21,6 @@ struct VoxelStreamInstanceDataRequest {
uint8_t lod;
};
} // namespace zylann::voxel
#endif // VOXEL_BLOCK_REQUEST_H

View File

@ -439,8 +439,6 @@ void BlockSerializer::deserialize(Ref<StreamPeer> peer, VoxelBufferInternal &vox
}
}
} // namespace zylann::voxel
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int VoxelBlockSerializer::serialize(Ref<StreamPeer> peer, Ref<VoxelBuffer> voxel_buffer, bool compress) {
@ -461,3 +459,5 @@ void VoxelBlockSerializer::_bind_methods() {
ClassDB::bind_method(
D_METHOD("deserialize", "peer", "voxel_buffer", "size", "decompress"), &VoxelBlockSerializer::deserialize);
}
} // namespace zylann::voxel

View File

@ -41,8 +41,6 @@ private:
FileAccessMemory _file_access_memory;
};
} // namespace zylann::voxel
class VoxelBuffer;
class VoxelBlockSerializer : public RefCounted {
@ -54,7 +52,9 @@ public:
private:
static void _bind_methods();
zylann::voxel::BlockSerializer _serializer;
BlockSerializer _serializer;
};
} // namespace zylann::voxel
#endif // VOXEL_BLOCK_SERIALIZER_H

View File

@ -5,6 +5,8 @@
#include "voxel_block_request.h"
#include <core/io/resource.h>
namespace zylann::voxel {
// Provides access to a source of paged voxel data, which may load and save.
// 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.
@ -36,10 +38,10 @@ public:
// 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.
virtual Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
virtual Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
// TODO Deprecate
virtual void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod);
virtual void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod);
// TODO Rename load_voxel_blocks
// Note: Don't modify the order of `p_blocks`.
@ -59,7 +61,7 @@ public:
struct FullLoadingResult {
struct Block {
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
std::shared_ptr<VoxelBufferInternal> voxels;
std::unique_ptr<VoxelInstanceBlockData> instances_data;
Vector3i position;
unsigned int lod;
@ -107,6 +109,8 @@ private:
RWLock _parameters_lock;
};
VARIANT_ENUM_CAST(VoxelStream::Result);
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelStream::Result);
#endif // VOXEL_STREAM_H

View File

@ -7,6 +7,8 @@
class FileAccess;
namespace zylann::voxel {
// Loads and saves blocks to the filesystem, under a directory.
// Each block gets its own file, which may produce a lot of them, but it makes it simple to implement.
// This is a naive implementation and may be very slow in practice, so maybe it will be removed in the future.
@ -15,8 +17,8 @@ class VoxelStreamBlockFiles : public VoxelStream {
public:
VoxelStreamBlockFiles();
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
int get_used_channels_mask() const override;
@ -29,13 +31,13 @@ protected:
static void _bind_methods();
private:
zylann::FileResult save_meta();
zylann::FileResult load_meta();
zylann::FileResult load_or_create_meta();
FileResult save_meta();
FileResult load_meta();
FileResult load_or_create_meta();
String get_block_file_path(const Vector3i &block_pos, unsigned int lod) const;
Vector3i get_block_position(const Vector3i &origin_in_voxels) const;
static thread_local zylann::voxel::BlockSerializer _block_serializer;
static thread_local BlockSerializer _block_serializer;
String _directory_path;
@ -43,8 +45,7 @@ private:
uint8_t version = -1;
uint8_t lod_count = 0;
uint8_t block_size_po2 = 0; // How many voxels in a block
zylann::FixedArray<zylann::voxel::VoxelBufferInternal::Depth, zylann::voxel::VoxelBufferInternal::MAX_CHANNELS>
channel_depths;
FixedArray<VoxelBufferInternal::Depth, VoxelBufferInternal::MAX_CHANNELS> channel_depths;
};
Meta _meta;
@ -52,4 +53,6 @@ private:
bool _meta_saved = false;
};
} // namespace zylann::voxel
#endif // VOXEL_STREAM_BLOCK_FILES_H

View File

@ -2,7 +2,7 @@
#include "../constants/voxel_string_names.h"
#include "../util/godot/funcs.h"
using namespace zylann::voxel;
namespace zylann::voxel {
VoxelStream::Result VoxelStreamScript::emerge_block(
VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) {
@ -60,3 +60,5 @@ void VoxelStreamScript::_bind_methods() {
// BIND_VMETHOD(MethodInfo(Variant::INT, "_get_used_channels_mask"));
}
} // namespace zylann::voxel

View File

@ -5,14 +5,16 @@
#include <core/object/script_language.h> // needed for GDVIRTUAL macro
#include <core/object/gdvirtual.gen.inc> // Also needed for GDVIRTUAL macro...
namespace zylann::voxel {
// Provides access to a source of paged voxel data, which may load and save.
// Must be implemented in a multi-thread-safe way.
// If you are looking for a more specialized API to generate voxels, use VoxelGenerator.
class VoxelStreamScript : public VoxelStream {
GDCLASS(VoxelStreamScript, VoxelStream)
public:
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
int get_used_channels_mask() const override;
@ -26,4 +28,6 @@ protected:
static void _bind_methods();
};
} // namespace zylann::voxel
#endif // VOXEL_STREAM_SCRIPT_H

View File

@ -4,6 +4,8 @@
#include "voxel_instancer.h"
#include <scene/main/node.h>
namespace zylann::voxel {
// Used as child of scene items instanced with VoxelInstancer.
//
// It is needed because such instances are tied with some of the logic in VoxelInstancer.
@ -109,4 +111,6 @@ private:
int _instance_index = -1;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCE_COMPONENT_H

View File

@ -5,7 +5,7 @@
#include <core/core_string_names.h>
#include <scene/resources/mesh.h>
using namespace zylann;
namespace zylann::voxel {
namespace {
const float MAX_DENSITY = 1.f;
@ -772,3 +772,5 @@ void VoxelInstanceGenerator::_bind_methods() {
BIND_ENUM_CONSTANT(DIMENSION_3D);
BIND_ENUM_CONSTANT(DIMENSION_COUNT);
}
} // namespace zylann::voxel

View File

@ -8,6 +8,8 @@
#include <limits>
#include <vector>
namespace zylann::voxel {
// TODO This may have to be moved to the meshing thread some day
// Decides where to spawn instances on top of a voxel surface.
@ -46,7 +48,11 @@ public:
DISTRIBUTION_COUNT
};
enum Dimension { DIMENSION_2D = 0, DIMENSION_3D, DIMENSION_COUNT };
enum Dimension { //
DIMENSION_2D = 0,
DIMENSION_3D,
DIMENSION_COUNT
};
// This API might change so for now it's not exposed to scripts
void generate_transforms(std::vector<Transform3D> &out_transforms, Vector3i grid_position, int lod_index,
@ -136,8 +142,10 @@ private:
float _max_slope_degrees = 180.f;
};
VARIANT_ENUM_CAST(VoxelInstanceGenerator::EmitMode);
VARIANT_ENUM_CAST(VoxelInstanceGenerator::Distribution);
VARIANT_ENUM_CAST(VoxelInstanceGenerator::Dimension);
} // namespace zylann::voxel
VARIANT_ENUM_CAST(zylann::voxel::VoxelInstanceGenerator::EmitMode);
VARIANT_ENUM_CAST(zylann::voxel::VoxelInstanceGenerator::Distribution);
VARIANT_ENUM_CAST(zylann::voxel::VoxelInstanceGenerator::Dimension);
#endif // VOXEL_INSTANCE_GENERATOR_H

View File

@ -5,6 +5,8 @@
#include <scene/3d/mesh_instance_3d.h>
#include <scene/3d/physics_body_3d.h>
namespace zylann::voxel {
VoxelInstanceLibrary::~VoxelInstanceLibrary() {
for_each_item([this](int id, VoxelInstanceLibraryItemBase &item) { item.remove_listener(this, id); });
}
@ -176,3 +178,5 @@ void VoxelInstanceLibrary::_bind_methods() {
BIND_CONSTANT(MAX_ID);
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include "voxel_instance_library_item_base.h"
namespace zylann::voxel {
// Contains a list of items that can be used by VoxelInstancer, associated with a unique ID
class VoxelInstanceLibrary : public Resource, public VoxelInstanceLibraryItemBase::IListener {
GDCLASS(VoxelInstanceLibrary, Resource)
@ -59,4 +61,6 @@ private:
Vector<IListener *> _listeners;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCER_LIBRARY_H

View File

@ -6,6 +6,8 @@
#include <scene/3d/mesh_instance_3d.h>
#include <scene/3d/physics_body_3d.h>
namespace zylann::voxel {
void VoxelInstanceLibraryItem::set_mesh(Ref<Mesh> mesh, int mesh_lod_index) {
ERR_FAIL_INDEX(mesh_lod_index, static_cast<int>(_mesh_lods.size()));
if (_mesh_lods[mesh_lod_index] == mesh) {
@ -262,3 +264,5 @@ void VoxelInstanceLibraryItem::_bind_methods() {
BIND_CONSTANT(MAX_MESH_LODS);
}
} // namespace zylann::voxel

View File

@ -7,6 +7,8 @@
// TODO Rename VoxelInstanceLibraryMultimeshItem (did not do it for compatibility)
namespace zylann::voxel {
// Settings for a model that can be used by VoxelInstancer
class VoxelInstanceLibraryItem : public VoxelInstanceLibraryItemBase {
GDCLASS(VoxelInstanceLibraryItem, VoxelInstanceLibraryItemBase)
@ -77,7 +79,7 @@ private:
set_mesh(mesh, 3);
}
zylann::FixedArray<Ref<Mesh>, MAX_MESH_LODS> _mesh_lods;
FixedArray<Ref<Mesh>, MAX_MESH_LODS> _mesh_lods;
unsigned int _mesh_lod_count = 1;
// It is preferred to have materials on the mesh already,
@ -91,4 +93,6 @@ private:
Vector<CollisionShapeInfo> _collision_shapes;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCE_LIBRARY_ITEM_H

View File

@ -3,6 +3,8 @@
#include <core/core_string_names.h>
namespace zylann::voxel {
void VoxelInstanceLibraryItemBase::set_item_name(String name) {
_name = name;
}
@ -103,3 +105,5 @@ void VoxelInstanceLibraryItemBase::_bind_methods() {
"set_generator", "get_generator");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "persistent"), "set_persistent", "is_persistent");
}
} // namespace zylann::voxel

View File

@ -6,10 +6,12 @@
// TODO Rename VoxelInstanceLibraryItem (did not do it for compatibility)
namespace zylann::voxel {
class VoxelInstanceLibraryItemBase : public Resource {
GDCLASS(VoxelInstanceLibraryItemBase, Resource)
public:
enum ChangeType {
enum ChangeType { //
CHANGE_LOD_INDEX,
CHANGE_GENERATOR,
CHANGE_VISUAL,
@ -75,4 +77,6 @@ private:
Vector<ListenerSlot> _listeners;
};
} // namespace zylann::voxel
#endif // VOXEL_INSTANCE_LIBRARY_ITEM_BASE_H

Some files were not shown because too many files have changed in this diff Show More