Show voxel bounds as min/max instead of pos/size
This commit is contained in:
parent
d6d592bb20
commit
97e4101234
@ -20,8 +20,8 @@ static const unsigned int MAX_BLOCK_COUNT_PER_REQUEST = 4 * 4 * 4;
|
|||||||
// Using a higher maximum can cause int32 overflows when calculating dimensions. There is no use case for it.
|
// Using a higher maximum can cause int32 overflows when calculating dimensions. There is no use case for it.
|
||||||
static const unsigned int MAX_LOD = 24;
|
static const unsigned int MAX_LOD = 24;
|
||||||
|
|
||||||
static const unsigned int MAX_VOLUME_EXTENT = 0x1fffffff;
|
static const int MAX_VOLUME_EXTENT = 0x1fffffff;
|
||||||
static const unsigned int MAX_VOLUME_SIZE = 2 * MAX_VOLUME_EXTENT; // 1,073,741,822 voxels
|
static const int MAX_VOLUME_SIZE = 2 * MAX_VOLUME_EXTENT; // 1,073,741,822 voxels
|
||||||
|
|
||||||
static const float INV_0x7f = 1.f / 0x7f;
|
static const float INV_0x7f = 1.f / 0x7f;
|
||||||
static const float INV_0x7fff = 1.f / 0x7fff;
|
static const float INV_0x7fff = 1.f / 0x7fff;
|
||||||
|
@ -21,6 +21,7 @@ Godot 4 is required from this version.
|
|||||||
- Added `ZN_ThreadedTask` to allow running custom tasks using the thread pool system
|
- Added `ZN_ThreadedTask` to allow running custom tasks using the thread pool system
|
||||||
- Added `VoxelMeshSDF` to bake SDF from meshes, which can be used in voxel sculpting.
|
- Added `VoxelMeshSDF` to bake SDF from meshes, which can be used in voxel sculpting.
|
||||||
- Mesh resources are now fully built on threads with the Godot Vulkan renderer
|
- Mesh resources are now fully built on threads with the Godot Vulkan renderer
|
||||||
|
- Editor: terrain bounds are now shown in the inspector as min/max instead of position/size
|
||||||
- `VoxelGeneratorGraph`: added support for outputting to the TYPE channel, allowing use with `VoxelMesherBlocky`
|
- `VoxelGeneratorGraph`: added support for outputting to the TYPE channel, allowing use with `VoxelMesherBlocky`
|
||||||
- `VoxelGeneratorGraph`: editor: unconnected inputs show their default value directly on the node
|
- `VoxelGeneratorGraph`: editor: unconnected inputs show their default value directly on the node
|
||||||
- `VoxelGeneratorGraph`: editor: allow to change the axes on preview nodes 3D slices
|
- `VoxelGeneratorGraph`: editor: allow to change the axes on preview nodes 3D slices
|
||||||
|
108
editor/terrain/editor_property_aabb_min_max.cpp
Normal file
108
editor/terrain/editor_property_aabb_min_max.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "editor_property_aabb_min_max.h"
|
||||||
|
#include <scene/gui/grid_container.h>
|
||||||
|
|
||||||
|
namespace zylann {
|
||||||
|
|
||||||
|
EditorPropertyAABBMinMax::EditorPropertyAABBMinMax() {
|
||||||
|
GridContainer *grid = memnew(GridContainer);
|
||||||
|
grid->set_columns(4);
|
||||||
|
add_child(grid);
|
||||||
|
|
||||||
|
for (int i = 0; i < _spin.size(); i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
Label *label = memnew(Label);
|
||||||
|
label->set_text("Min");
|
||||||
|
grid->add_child(label);
|
||||||
|
|
||||||
|
} else if (i == 3) {
|
||||||
|
Label *label = memnew(Label);
|
||||||
|
label->set_text("Max");
|
||||||
|
grid->add_child(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorSpinSlider *sb = memnew(EditorSpinSlider);
|
||||||
|
sb->set_flat(true);
|
||||||
|
sb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
sb->connect("value_changed", callable_mp(this, &EditorPropertyAABBMinMax::_value_changed), varray(i));
|
||||||
|
_spin[i] = sb;
|
||||||
|
|
||||||
|
add_focusable(sb);
|
||||||
|
|
||||||
|
grid->add_child(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
_spin[0]->set_label("X");
|
||||||
|
_spin[1]->set_label("Y");
|
||||||
|
_spin[2]->set_label("Z");
|
||||||
|
_spin[3]->set_label("X");
|
||||||
|
_spin[4]->set_label("Y");
|
||||||
|
_spin[5]->set_label("Z");
|
||||||
|
|
||||||
|
set_bottom_editor(grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::_set_read_only(bool p_read_only) {
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
_spin[i]->set_read_only(p_read_only);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::_value_changed(double val, int spinbox_index) {
|
||||||
|
if (_setting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AABB p;
|
||||||
|
p.position.x = _spin[0]->get_value();
|
||||||
|
p.position.y = _spin[1]->get_value();
|
||||||
|
p.position.z = _spin[2]->get_value();
|
||||||
|
p.size.x = _spin[3]->get_value() - p.position.x;
|
||||||
|
p.size.y = _spin[4]->get_value() - p.position.y;
|
||||||
|
p.size.z = _spin[5]->get_value() - p.position.z;
|
||||||
|
|
||||||
|
emit_changed(get_edited_property(), p, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::update_property() {
|
||||||
|
const AABB val = get_edited_object()->get(get_edited_property());
|
||||||
|
|
||||||
|
_setting = true;
|
||||||
|
|
||||||
|
_spin[0]->set_value(val.position.x);
|
||||||
|
_spin[1]->set_value(val.position.y);
|
||||||
|
_spin[2]->set_value(val.position.z);
|
||||||
|
_spin[3]->set_value(val.position.x + val.size.x);
|
||||||
|
_spin[4]->set_value(val.position.y + val.size.y);
|
||||||
|
_spin[5]->set_value(val.position.z + val.size.z);
|
||||||
|
|
||||||
|
_setting = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE:
|
||||||
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
const Color *colors = _get_property_colors();
|
||||||
|
for (unsigned int i = 0; i < _spin.size(); i++) {
|
||||||
|
_spin[i]->add_theme_color_override("label_color", colors[i % 3]);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::setup(
|
||||||
|
double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) {
|
||||||
|
for (int i = 0; i < _spin.size(); i++) {
|
||||||
|
_spin[i]->set_min(p_min);
|
||||||
|
_spin[i]->set_max(p_max);
|
||||||
|
_spin[i]->set_step(p_step);
|
||||||
|
_spin[i]->set_hide_slider(p_no_slider);
|
||||||
|
_spin[i]->set_allow_greater(true);
|
||||||
|
_spin[i]->set_allow_lesser(true);
|
||||||
|
_spin[i]->set_suffix(p_suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyAABBMinMax::_bind_methods() {}
|
||||||
|
|
||||||
|
} // namespace zylann
|
37
editor/terrain/editor_property_aabb_min_max.h
Normal file
37
editor/terrain/editor_property_aabb_min_max.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef ZYLANN_EDITOR_PROPERTY_AABB_H
|
||||||
|
#define ZYLANN_EDITOR_PROPERTY_AABB_H
|
||||||
|
|
||||||
|
#include <editor/editor_inspector.h>
|
||||||
|
#include <editor/editor_spin_slider.h>
|
||||||
|
|
||||||
|
#include "../../util/fixed_array.h"
|
||||||
|
|
||||||
|
namespace zylann {
|
||||||
|
|
||||||
|
// Alternative to the default AABB editor which presents it as a minimum and maximum point
|
||||||
|
class EditorPropertyAABBMinMax : public EditorProperty {
|
||||||
|
GDCLASS(EditorPropertyAABBMinMax, EditorProperty);
|
||||||
|
|
||||||
|
public:
|
||||||
|
EditorPropertyAABBMinMax();
|
||||||
|
|
||||||
|
void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String());
|
||||||
|
|
||||||
|
virtual void update_property() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _set_read_only(bool p_read_only) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _value_changed(double p_val, int spinbox_index);
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
FixedArray<EditorSpinSlider *, 6> _spin;
|
||||||
|
bool _setting = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace zylann
|
||||||
|
|
||||||
|
#endif // ZYLANN_EDITOR_PROPERTY_AABB_H
|
37
editor/terrain/voxel_terrain_editor_inspector_plugin.cpp
Normal file
37
editor/terrain/voxel_terrain_editor_inspector_plugin.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "voxel_terrain_editor_inspector_plugin.h"
|
||||||
|
#include "../../terrain/fixed_lod/voxel_terrain.h"
|
||||||
|
#include "../../terrain/variable_lod/voxel_lod_terrain.h"
|
||||||
|
#include "editor_property_aabb_min_max.h"
|
||||||
|
|
||||||
|
namespace zylann::voxel {
|
||||||
|
|
||||||
|
bool VoxelTerrainEditorInspectorPlugin::can_handle(Object *p_object) {
|
||||||
|
const VoxelTerrain *vt = Object::cast_to<VoxelTerrain>(p_object);
|
||||||
|
if (vt != nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const VoxelLodTerrain *vlt = Object::cast_to<VoxelLodTerrain>(p_object);
|
||||||
|
if (vlt != nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VoxelTerrainEditorInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type,
|
||||||
|
const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage,
|
||||||
|
const bool p_wide) {
|
||||||
|
if (p_type != Variant::AABB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO Give the same name to these properties
|
||||||
|
if (p_path != "voxel_bounds" && p_path != "bounds") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Replace default AABB editor with this one
|
||||||
|
EditorPropertyAABBMinMax *ed = memnew(EditorPropertyAABBMinMax);
|
||||||
|
ed->setup(-constants::MAX_VOLUME_EXTENT, constants::MAX_VOLUME_EXTENT, 1, true);
|
||||||
|
add_property_editor(p_path, ed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace zylann::voxel
|
18
editor/terrain/voxel_terrain_editor_inspector_plugin.h
Normal file
18
editor/terrain/voxel_terrain_editor_inspector_plugin.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef VOXEL_TERRAIN_EDITOR_INSPECTOR_PLUGIN_H
|
||||||
|
#define VOXEL_TERRAIN_EDITOR_INSPECTOR_PLUGIN_H
|
||||||
|
|
||||||
|
#include <editor/editor_inspector.h>
|
||||||
|
|
||||||
|
namespace zylann::voxel {
|
||||||
|
|
||||||
|
class VoxelTerrainEditorInspectorPlugin : public EditorInspectorPlugin {
|
||||||
|
GDCLASS(VoxelTerrainEditorInspectorPlugin, EditorInspectorPlugin)
|
||||||
|
public:
|
||||||
|
bool can_handle(Object *p_object) override;
|
||||||
|
bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint,
|
||||||
|
const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace zylann::voxel
|
||||||
|
|
||||||
|
#endif // VOXEL_TERRAIN_EDITOR_INSPECTOR_PLUGIN_H
|
@ -78,10 +78,14 @@ void VoxelTerrainEditorPlugin::_notification(int p_what) {
|
|||||||
VoxelServer::get_singleton().set_viewer_distance(_editor_viewer_id, 512);
|
VoxelServer::get_singleton().set_viewer_distance(_editor_viewer_id, 512);
|
||||||
// No collision needed in editor, also it updates faster without
|
// No collision needed in editor, also it updates faster without
|
||||||
VoxelServer::get_singleton().set_viewer_requires_collisions(_editor_viewer_id, false);
|
VoxelServer::get_singleton().set_viewer_requires_collisions(_editor_viewer_id, false);
|
||||||
|
|
||||||
|
_inspector_plugin.instantiate();
|
||||||
|
add_inspector_plugin(_inspector_plugin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
VoxelServer::get_singleton().remove_viewer(_editor_viewer_id);
|
VoxelServer::get_singleton().remove_viewer(_editor_viewer_id);
|
||||||
|
remove_inspector_plugin(_inspector_plugin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOTIFICATION_PROCESS:
|
case NOTIFICATION_PROCESS:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef VOXEL_TERRAIN_EDITOR_PLUGIN_H
|
#ifndef VOXEL_TERRAIN_EDITOR_PLUGIN_H
|
||||||
#define VOXEL_TERRAIN_EDITOR_PLUGIN_H
|
#define VOXEL_TERRAIN_EDITOR_PLUGIN_H
|
||||||
|
|
||||||
|
#include "voxel_terrain_editor_inspector_plugin.h"
|
||||||
#include <editor/editor_plugin.h>
|
#include <editor/editor_plugin.h>
|
||||||
|
|
||||||
class MenuButton;
|
class MenuButton;
|
||||||
@ -56,6 +57,7 @@ private:
|
|||||||
MenuButton *_menu_button = nullptr;
|
MenuButton *_menu_button = nullptr;
|
||||||
VoxelAboutWindow *_about_window = nullptr;
|
VoxelAboutWindow *_about_window = nullptr;
|
||||||
VoxelTerrainEditorTaskIndicator *_task_indicator = nullptr;
|
VoxelTerrainEditorTaskIndicator *_task_indicator = nullptr;
|
||||||
|
Ref<VoxelTerrainEditorInspectorPlugin> _inspector_plugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace zylann::voxel
|
} // namespace zylann::voxel
|
||||||
|
Loading…
x
Reference in New Issue
Block a user