Draw instance chunks in editor

master
Marc Gilleron 2021-12-30 22:20:30 +00:00
parent 272bf4bd8f
commit 3db4798e14
8 changed files with 145 additions and 1 deletions

1
SCsub
View File

@ -59,6 +59,7 @@ if env["tools"]:
"editor/graph/*.cpp",
"editor/terrain/*.cpp",
"editor/fast_noise_lite/*.cpp",
"editor/instancer/*.cpp",
"editor/instance_library/*.cpp",
"editor/vox/*.cpp",
]

View File

@ -0,0 +1,25 @@
#include "voxel_instancer_editor_plugin.h"
#include "../../terrain/instancing/voxel_instancer.h"
VoxelInstancerEditorPlugin::VoxelInstancerEditorPlugin(EditorNode *p_node) {}
bool VoxelInstancerEditorPlugin::handles(Object *p_object) const {
ERR_FAIL_COND_V(p_object == nullptr, false);
return Object::cast_to<VoxelInstancer>(p_object) != nullptr;
}
void VoxelInstancerEditorPlugin::edit(Object *p_object) {
VoxelInstancer *instancer = Object::cast_to<VoxelInstancer>(p_object);
ERR_FAIL_COND(instancer == nullptr);
instancer->set_show_gizmos(true);
_node = instancer;
}
void VoxelInstancerEditorPlugin::make_visible(bool visible) {
if (visible == false) {
if (_node != nullptr) {
_node->set_show_gizmos(false);
_node = nullptr;
}
}
}

View File

@ -0,0 +1,21 @@
#ifndef VOXEL_INSTANCER_EDITOR_PLUGIN_H
#define VOXEL_INSTANCER_EDITOR_PLUGIN_H
#include <editor/editor_plugin.h>
class VoxelInstancer;
class VoxelInstancerEditorPlugin : public EditorPlugin {
GDCLASS(VoxelInstancerEditorPlugin, EditorPlugin)
public:
VoxelInstancerEditorPlugin(EditorNode *p_node);
bool handles(Object *p_object) const override;
void edit(Object *p_object) override;
void make_visible(bool visible) override;
private:
VoxelInstancer *_node = nullptr;
};
#endif // VOXEL_INSTANCER_EDITOR_PLUGIN_H

View File

@ -252,7 +252,7 @@ void DebugMultiMeshRenderer::begin() {
}
void DebugMultiMeshRenderer::draw_box(const Transform3D &t, Color8 color) {
_items.push_back(DirectMultiMeshInstance::TransformAndColor32{ t, color });
_items.push_back(DirectMultiMeshInstance::TransformAndColor32{ t, Color(color) });
}
void DebugMultiMeshRenderer::end() {

View File

@ -37,6 +37,7 @@ private:
std::vector<DirectMultiMeshInstance::TransformAndColor32> _items;
Ref<MultiMesh> _multimesh;
DirectMultiMeshInstance _multimesh_instance;
// TODO World3D is a reference, do not store it by pointer
World3D *_world = nullptr;
bool _inside_block = false;
PackedFloat32Array _bulk_array;
@ -49,18 +50,28 @@ class DebugRenderer {
public:
~DebugRenderer();
// This class does not uses nodes. Call this first to choose in which world it renders.
void set_world(World3D *world);
// Call this before issuing drawing commands
void begin();
void draw_box(const Transform3D &t, ColorID color);
// Draws a box wireframe using MultiMesh, allowing to draw much more without slowing down.
// The box's origin is its lower corner. Size is defined by the transform's basis.
void draw_box_mm(const Transform3D &t, Color8 color);
// Call this after issuing all drawing commands
void end();
void clear();
private:
std::vector<DebugRendererItem *> _items;
unsigned int _current = 0;
bool _inside_block = false;
// TODO World3D is a reference, do not store it by pointer
World3D *_world = nullptr;
DebugMultiMeshRenderer _mm_renderer;
};

View File

@ -47,6 +47,7 @@
#include "editor/fast_noise_lite/fast_noise_lite_editor_plugin.h"
#include "editor/graph/voxel_graph_editor_plugin.h"
#include "editor/instance_library/voxel_instance_library_editor_plugin.h"
#include "editor/instancer/voxel_instancer_editor_plugin.h"
#include "editor/terrain/voxel_terrain_editor_plugin.h"
#include "editor/vox/vox_editor_plugin.h"
#include "editor/voxel_debug.h"
@ -151,6 +152,7 @@ void register_voxel_types() {
EditorPlugins::add_by_type<VoxelInstanceLibraryEditorPlugin>();
EditorPlugins::add_by_type<FastNoiseLiteEditorPlugin>();
EditorPlugins::add_by_type<VoxEditorPlugin>();
EditorPlugins::add_by_type<VoxelInstancerEditorPlugin>();
#endif
#ifdef VOXEL_RUN_TESTS

View File

@ -90,10 +90,16 @@ void VoxelInstancer::_notification(int p_what) {
case NOTIFICATION_ENTER_WORLD:
set_world(*get_world_3d());
update_visibility();
#ifdef TOOLS_ENABLED
_debug_renderer.set_world(get_world_3d().ptr());
#endif
break;
case NOTIFICATION_EXIT_WORLD:
set_world(nullptr);
#ifdef TOOLS_ENABLED
_debug_renderer.set_world(nullptr);
#endif
break;
case NOTIFICATION_PARENTED:
@ -141,16 +147,77 @@ void VoxelInstancer::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED:
update_visibility();
#ifdef TOOLS_ENABLED
if (_gizmos_enabled) {
_debug_renderer.set_world(is_visible_in_tree() ? *get_world_3d() : nullptr);
}
#endif
break;
case NOTIFICATION_INTERNAL_PROCESS:
if (_parent != nullptr && _library.is_valid()) {
process_mesh_lods();
}
#ifdef TOOLS_ENABLED
if (_gizmos_enabled) {
process_gizmos();
}
#endif
break;
}
}
#ifdef TOOLS_ENABLED
void VoxelInstancer::set_show_gizmos(bool enable) {
_gizmos_enabled = enable;
if (_gizmos_enabled) {
_debug_renderer.set_world(is_visible_in_tree() ? *get_world_3d() : nullptr);
} else {
_debug_renderer.clear();
}
}
void VoxelInstancer::process_gizmos() {
ERR_FAIL_COND(_parent == nullptr);
const Transform3D parent_transform = get_global_transform();
const int base_block_size_po2 = _parent->get_mesh_block_size_pow2();
_debug_renderer.begin();
for (auto it = _blocks.begin(); it != _blocks.end(); ++it) {
const Block *block = *it;
CRASH_COND(block == nullptr);
Color8 color(0, 255, 0, 255);
if (block->multimesh_instance.is_valid()) {
if (block->multimesh_instance.get_multimesh().is_null()) {
// Allocated but without multimesh (wut?)
color = Color8(128, 0, 0, 255);
} else if (get_visible_instance_count(**block->multimesh_instance.get_multimesh()) == 0) {
// Allocated but empty multimesh
color = Color8(255, 64, 0, 255);
}
} else if (block->scene_instances.size() == 0) {
// Only draw blocks that are setup
continue;
}
const int block_size_po2 = base_block_size_po2 + block->lod_index;
const int block_size = 1 << block_size_po2;
const Vector3 block_local_pos(block->grid_position << block_size_po2);
const Transform3D box_transform(
parent_transform.basis * (Basis().scaled(Vector3(block_size, block_size, block_size))),
parent_transform.xform(block_local_pos));
_debug_renderer.draw_box_mm(box_transform, color);
}
_debug_renderer.end();
}
#endif
VoxelInstancer::Layer *VoxelInstancer::get_layer(int id) {
Layer *ptr = _layers.getptr(id);
CRASH_COND(ptr == nullptr);

View File

@ -9,6 +9,10 @@
#include "voxel_instance_library.h"
#include "voxel_instance_library_item.h"
#ifdef TOOLS_ENABLED
#include "../../editor/voxel_debug.h"
#endif
#include <scene/3d/node_3d.h>
//#include <scene/resources/material.h> // Included by node.h lol
#include <limits>
@ -72,6 +76,10 @@ public:
void debug_dump_as_scene(String fpath) const;
Node *debug_dump_as_nodes() const;
#ifdef TOOLS_ENABLED
void set_show_gizmos(bool enable);
#endif
TypedArray<String> get_configuration_warnings() const override;
protected:
@ -100,6 +108,10 @@ private:
void update_layer_scenes(int layer_id);
void create_render_blocks(Vector3i grid_position, int lod_index, Array surface_arrays);
#ifdef TOOLS_ENABLED
void process_gizmos();
#endif
struct SceneInstance {
VoxelInstanceComponent *component = nullptr;
Node3D *root = nullptr;
@ -192,6 +204,11 @@ private:
std::vector<Transform3D> _transform_cache;
VoxelLodTerrain *_parent;
#ifdef TOOLS_ENABLED
VoxelDebug::DebugRenderer _debug_renderer;
bool _gizmos_enabled = true;
#endif
};
VARIANT_ENUM_CAST(VoxelInstancer::UpMode);