mirror of
https://github.com/Relintai/voxelman.git
synced 2025-04-25 21:25:00 +02:00
Implement isolevel support for the voxel editor.
This commit is contained in:
parent
33030e485a
commit
e14bc67da8
@ -698,7 +698,7 @@ uint8_t VoxelWorld::get_voxel_at_world_position(const Vector3 &world_position, c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelWorld::set_voxel_at_world_position(const Vector3 &world_position, const uint8_t data, const int channel_index) {
|
void VoxelWorld::set_voxel_at_world_position(const Vector3 &world_position, const uint8_t data, const int channel_index, const bool rebuild) {
|
||||||
Vector3 pos = world_position / get_voxel_scale();
|
Vector3 pos = world_position / get_voxel_scale();
|
||||||
|
|
||||||
//Note: floor is needed to handle negative numbers proiberly
|
//Note: floor is needed to handle negative numbers proiberly
|
||||||
@ -726,19 +726,25 @@ void VoxelWorld::set_voxel_at_world_position(const Vector3 &world_position, cons
|
|||||||
if (bx == 0) {
|
if (bx == 0) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x - 1, y, z);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x - 1, y, z);
|
||||||
chunk->set_voxel(data, get_chunk_size_x(), by, bz, channel_index);
|
chunk->set_voxel(data, get_chunk_size_x(), by, bz, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (by == 0) {
|
if (by == 0) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y - 1, z);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y - 1, z);
|
||||||
chunk->set_voxel(data, bx, get_chunk_size_y(), bz, channel_index);
|
chunk->set_voxel(data, bx, get_chunk_size_y(), bz, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bz == 0) {
|
if (bz == 0) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z - 1);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z - 1);
|
||||||
chunk->set_voxel(data, bx, by, get_chunk_size_z(), channel_index);
|
chunk->set_voxel(data, bx, by, get_chunk_size_z(), channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,25 +752,33 @@ void VoxelWorld::set_voxel_at_world_position(const Vector3 &world_position, cons
|
|||||||
if (bx == get_chunk_size_x() - 1) {
|
if (bx == get_chunk_size_x() - 1) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x + 1, y, z);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x + 1, y, z);
|
||||||
chunk->set_voxel(data, -1, by, bz, channel_index);
|
chunk->set_voxel(data, -1, by, bz, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (by == get_chunk_size_y() - 1) {
|
if (by == get_chunk_size_y() - 1) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y + 1, z);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y + 1, z);
|
||||||
chunk->set_voxel(data, bx, -1, bz, channel_index);
|
chunk->set_voxel(data, bx, -1, bz, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bz == get_chunk_size_z() - 1) {
|
if (bz == get_chunk_size_z() - 1) {
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z + 1);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z + 1);
|
||||||
chunk->set_voxel(data, bx, by, -1, channel_index);
|
chunk->set_voxel(data, bx, by, -1, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z);
|
Ref<VoxelChunk> chunk = get_or_create_chunk(x, y, z);
|
||||||
chunk->set_voxel(data, bx, by, bz, channel_index);
|
chunk->set_voxel(data, bx, by, bz, channel_index);
|
||||||
chunk->build();
|
|
||||||
|
if (rebuild)
|
||||||
|
chunk->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<VoxelChunk> VoxelWorld::get_chunk_at_world_position(const Vector3 &world_position) {
|
Ref<VoxelChunk> VoxelWorld::get_chunk_at_world_position(const Vector3 &world_position) {
|
||||||
@ -1120,7 +1134,7 @@ void VoxelWorld::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_lights", "chunks"), &VoxelWorld::set_lights);
|
ClassDB::bind_method(D_METHOD("set_lights", "chunks"), &VoxelWorld::set_lights);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_voxel_at_world_position", "world_position", "channel_index"), &VoxelWorld::get_voxel_at_world_position);
|
ClassDB::bind_method(D_METHOD("get_voxel_at_world_position", "world_position", "channel_index"), &VoxelWorld::get_voxel_at_world_position);
|
||||||
ClassDB::bind_method(D_METHOD("set_voxel_at_world_position", "world_position", "data", "channel_index"), &VoxelWorld::set_voxel_at_world_position);
|
ClassDB::bind_method(D_METHOD("set_voxel_at_world_position", "world_position", "data", "channel_index", "rebuild"), &VoxelWorld::set_voxel_at_world_position, DEFVAL(true));
|
||||||
ClassDB::bind_method(D_METHOD("get_chunk_at_world_position", "world_position"), &VoxelWorld::get_chunk_at_world_position);
|
ClassDB::bind_method(D_METHOD("get_chunk_at_world_position", "world_position"), &VoxelWorld::get_chunk_at_world_position);
|
||||||
ClassDB::bind_method(D_METHOD("get_or_create_chunk_at_world_position", "world_position"), &VoxelWorld::get_or_create_chunk_at_world_position);
|
ClassDB::bind_method(D_METHOD("get_or_create_chunk_at_world_position", "world_position"), &VoxelWorld::get_or_create_chunk_at_world_position);
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ public:
|
|||||||
|
|
||||||
//Helpers
|
//Helpers
|
||||||
uint8_t get_voxel_at_world_position(const Vector3 &world_position, const int channel_index);
|
uint8_t get_voxel_at_world_position(const Vector3 &world_position, const int channel_index);
|
||||||
void set_voxel_at_world_position(const Vector3 &world_position, const uint8_t data, const int channel_index);
|
void set_voxel_at_world_position(const Vector3 &world_position, const uint8_t data, const int channel_index, const bool rebuild = true);
|
||||||
Ref<VoxelChunk> get_chunk_at_world_position(const Vector3 &world_position);
|
Ref<VoxelChunk> get_chunk_at_world_position(const Vector3 &world_position);
|
||||||
Ref<VoxelChunk> get_or_create_chunk_at_world_position(const Vector3 &world_position);
|
Ref<VoxelChunk> get_or_create_chunk_at_world_position(const Vector3 &world_position);
|
||||||
|
|
||||||
|
@ -95,15 +95,23 @@ bool VoxelWorldEditor::do_input_action(Camera *p_camera, const Point2 &p_point,
|
|||||||
if (channel == -1)
|
if (channel == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int isolevel = _current_isolevel;
|
||||||
|
|
||||||
if (_tool_mode == TOOL_MODE_ADD) {
|
if (_tool_mode == TOOL_MODE_ADD) {
|
||||||
pos = (res.position + (Vector3(0.1, 0.1, 0.1) * res.normal));
|
pos = (res.position + (Vector3(0.1, 0.1, 0.1) * res.normal));
|
||||||
selected_voxel = _selected_type + 1;
|
selected_voxel = _selected_type + 1;
|
||||||
} else if (_tool_mode == TOOL_MODE_REMOVE) {
|
} else if (_tool_mode == TOOL_MODE_REMOVE) {
|
||||||
pos = (res.position + (Vector3(0.1, 0.1, 0.1) * -res.normal));
|
pos = (res.position + (Vector3(0.1, 0.1, 0.1) * -res.normal));
|
||||||
selected_voxel = 0;
|
selected_voxel = 0;
|
||||||
|
isolevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_world->set_voxel_at_world_position(pos, selected_voxel, channel);
|
if (_channel_isolevel == -1) {
|
||||||
|
_world->set_voxel_at_world_position(pos, selected_voxel, channel);
|
||||||
|
} else {
|
||||||
|
_world->set_voxel_at_world_position(pos, selected_voxel, channel, false);
|
||||||
|
_world->set_voxel_at_world_position(pos, isolevel, _channel_isolevel);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -118,6 +126,13 @@ void VoxelWorldEditor::edit(VoxelWorld *p_world) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_channel_type = _world->get_channel_index_info(VoxelWorld::CHANNEL_TYPE_INFO_TYPE);
|
_channel_type = _world->get_channel_index_info(VoxelWorld::CHANNEL_TYPE_INFO_TYPE);
|
||||||
|
_channel_isolevel = _world->get_channel_index_info(VoxelWorld::CHANNEL_TYPE_INFO_ISOLEVEL);
|
||||||
|
|
||||||
|
if (_channel_isolevel == -1) {
|
||||||
|
_isolevel_slider->hide();
|
||||||
|
} else {
|
||||||
|
_isolevel_slider->show();
|
||||||
|
}
|
||||||
|
|
||||||
spatial_editor = Object::cast_to<SpatialEditorPlugin>(_editor->get_editor_plugin_screen());
|
spatial_editor = Object::cast_to<SpatialEditorPlugin>(_editor->get_editor_plugin_screen());
|
||||||
|
|
||||||
@ -169,6 +184,8 @@ VoxelWorldEditor::VoxelWorldEditor() {
|
|||||||
_world = NULL;
|
_world = NULL;
|
||||||
_selected_type = 0;
|
_selected_type = 0;
|
||||||
_channel_type = -1;
|
_channel_type = -1;
|
||||||
|
_current_isolevel = 255;
|
||||||
|
_channel_isolevel = -1;
|
||||||
_editor = NULL;
|
_editor = NULL;
|
||||||
_tool_mode = TOOL_MODE_ADD;
|
_tool_mode = TOOL_MODE_ADD;
|
||||||
}
|
}
|
||||||
@ -176,6 +193,9 @@ VoxelWorldEditor::VoxelWorldEditor(EditorNode *p_editor) {
|
|||||||
_world = NULL;
|
_world = NULL;
|
||||||
_selected_type = 0;
|
_selected_type = 0;
|
||||||
_channel_type = -1;
|
_channel_type = -1;
|
||||||
|
_current_isolevel = 255;
|
||||||
|
_channel_isolevel = -1;
|
||||||
|
|
||||||
_editor = p_editor;
|
_editor = p_editor;
|
||||||
_tool_mode = TOOL_MODE_ADD;
|
_tool_mode = TOOL_MODE_ADD;
|
||||||
|
|
||||||
@ -219,6 +239,18 @@ VoxelWorldEditor::VoxelWorldEditor(EditorNode *p_editor) {
|
|||||||
|
|
||||||
set_custom_minimum_size(Size2(200 * EDSCALE, 0));
|
set_custom_minimum_size(Size2(200 * EDSCALE, 0));
|
||||||
|
|
||||||
|
_isolevel_slider = memnew(HSlider);
|
||||||
|
_isolevel_slider->set_min(1);
|
||||||
|
_isolevel_slider->set_max(255);
|
||||||
|
_isolevel_slider->set_value(_current_isolevel);
|
||||||
|
_isolevel_slider->set_custom_minimum_size(Size2(50 * EDSCALE, 0));
|
||||||
|
_isolevel_slider->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
spatial_editor_hb->add_child(_isolevel_slider);
|
||||||
|
|
||||||
|
_isolevel_slider->CONNECT("value_changed", this, VoxelWorldEditor, _on_isolevel_slider_value_changed);
|
||||||
|
|
||||||
|
_isolevel_slider->hide();
|
||||||
|
|
||||||
ScrollContainer *scs = memnew(ScrollContainer);
|
ScrollContainer *scs = memnew(ScrollContainer);
|
||||||
scs->set_h_size_flags(SIZE_EXPAND_FILL);
|
scs->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
scs->set_v_size_flags(SIZE_EXPAND_FILL);
|
scs->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
@ -280,7 +312,16 @@ void VoxelWorldEditor::_on_insert_block_at_camera_button_pressed() {
|
|||||||
Vector3 pos = cam->get_transform().origin;
|
Vector3 pos = cam->get_transform().origin;
|
||||||
selected_voxel = _selected_type + 1;
|
selected_voxel = _selected_type + 1;
|
||||||
|
|
||||||
_world->set_voxel_at_world_position(pos, selected_voxel, channel);
|
if (_channel_isolevel == -1) {
|
||||||
|
_world->set_voxel_at_world_position(pos, selected_voxel, channel);
|
||||||
|
} else {
|
||||||
|
_world->set_voxel_at_world_position(pos, selected_voxel, channel, false);
|
||||||
|
_world->set_voxel_at_world_position(pos, _current_isolevel, _channel_isolevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelWorldEditor::_on_isolevel_slider_value_changed(float value) {
|
||||||
|
_current_isolevel = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelWorldEditor::_bind_methods() {
|
void VoxelWorldEditor::_bind_methods() {
|
||||||
@ -288,6 +329,7 @@ void VoxelWorldEditor::_bind_methods() {
|
|||||||
ClassDB::bind_method("_on_surface_button_pressed", &VoxelWorldEditor::_on_surface_button_pressed);
|
ClassDB::bind_method("_on_surface_button_pressed", &VoxelWorldEditor::_on_surface_button_pressed);
|
||||||
ClassDB::bind_method("_on_tool_button_pressed", &VoxelWorldEditor::_on_tool_button_pressed);
|
ClassDB::bind_method("_on_tool_button_pressed", &VoxelWorldEditor::_on_tool_button_pressed);
|
||||||
ClassDB::bind_method("_on_insert_block_at_camera_button_pressed", &VoxelWorldEditor::_on_insert_block_at_camera_button_pressed);
|
ClassDB::bind_method("_on_insert_block_at_camera_button_pressed", &VoxelWorldEditor::_on_insert_block_at_camera_button_pressed);
|
||||||
|
ClassDB::bind_method("_on_isolevel_slider_value_changed", &VoxelWorldEditor::_on_isolevel_slider_value_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelWorldEditorPlugin::_notification(int p_what) {
|
void VoxelWorldEditorPlugin::_notification(int p_what) {
|
||||||
|
@ -58,6 +58,7 @@ protected:
|
|||||||
void _on_surface_button_pressed();
|
void _on_surface_button_pressed();
|
||||||
void _on_tool_button_pressed();
|
void _on_tool_button_pressed();
|
||||||
void _on_insert_block_at_camera_button_pressed();
|
void _on_insert_block_at_camera_button_pressed();
|
||||||
|
void _on_isolevel_slider_value_changed(float value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VBoxContainer *_surfaces_vbox_container;
|
VBoxContainer *_surfaces_vbox_container;
|
||||||
@ -68,12 +69,16 @@ private:
|
|||||||
VoxelWorldEditorToolMode _tool_mode;
|
VoxelWorldEditorToolMode _tool_mode;
|
||||||
VoxelWorld *_world;
|
VoxelWorld *_world;
|
||||||
|
|
||||||
|
HSlider *_isolevel_slider;
|
||||||
|
|
||||||
int _selected_type;
|
int _selected_type;
|
||||||
|
int _current_isolevel;
|
||||||
|
|
||||||
SpatialEditorPlugin *spatial_editor;
|
SpatialEditorPlugin *spatial_editor;
|
||||||
EditorNode *_editor;
|
EditorNode *_editor;
|
||||||
|
|
||||||
int _channel_type;
|
int _channel_type;
|
||||||
|
int _channel_isolevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VoxelWorldEditorPlugin : public EditorPlugin {
|
class VoxelWorldEditorPlugin : public EditorPlugin {
|
||||||
|
Loading…
Reference in New Issue
Block a user