Implemented the TerrainWorldGizmo.

This commit is contained in:
Relintai 2025-02-05 14:01:01 +01:00
parent dbff74222c
commit b1e386fd73
6 changed files with 188 additions and 33 deletions

View File

@ -38,6 +38,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "terrain_world_gizmo.h"
#include "terrain_world_gizmo_plugin.h"
#include "../world/terrain_world.h"
@ -79,6 +80,42 @@ EditorPlugin::AfterGUIInput TerrainWorldEditor::forward_spatial_input_event(Came
if (mm.is_valid()) {
if (!_mouse_down) {
switch (_tool_mode) {
case TOOL_MODE_ADD:
case TOOL_MODE_REMOVE: {
} break;
case TOOL_MODE_ISOLEVEL_BRUSH: {
Vector3 position;
Vector3 normal;
if (get_draw_world_coordinate(p_camera, Point2(mm->get_position().x, mm->get_position().y), position, normal)) {
_gizmo->visible = true;
_gizmo->drawing = false;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
} else {
_gizmo->visible = false;
_gizmo->redraw();
}
} break;
case TOOL_MODE_PAINT_BRUSH: {
Vector3 position;
Vector3 normal;
if (get_draw_world_coordinate(p_camera, Point2(mm->get_position().x, mm->get_position().y), position, normal)) {
_gizmo->visible = true;
_gizmo->drawing = false;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
} else {
_gizmo->visible = false;
_gizmo->redraw();
}
} break;
case TOOL_MODE_PAINT_PICKER: {
} break;
}
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}
@ -92,6 +129,14 @@ EditorPlugin::AfterGUIInput TerrainWorldEditor::forward_spatial_input_event(Came
if (get_draw_world_coordinate(p_camera, Point2(mm->get_position().x, mm->get_position().y), position, normal)) {
isolevel_brush_draw(position);
_gizmo->visible = true;
_gizmo->drawing = true;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
} else {
_gizmo->visible = false;
_gizmo->redraw();
}
} break;
case TOOL_MODE_PAINT_BRUSH: {
@ -100,6 +145,14 @@ EditorPlugin::AfterGUIInput TerrainWorldEditor::forward_spatial_input_event(Came
if (get_draw_world_coordinate(p_camera, Point2(mm->get_position().x, mm->get_position().y), position, normal)) {
paint_brush_draw(position);
_gizmo->visible = true;
_gizmo->drawing = true;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
} else {
_gizmo->visible = false;
_gizmo->redraw();
}
} break;
case TOOL_MODE_PAINT_PICKER: {
@ -127,8 +180,16 @@ EditorPlugin::AfterGUIInput TerrainWorldEditor::forward_spatial_input_event(Came
isolevel_brush_draw(position);
_gizmo->visible = true;
_gizmo->drawing = true;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else {
_gizmo->visible = false;
_gizmo->redraw();
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}
} break;
@ -141,8 +202,16 @@ EditorPlugin::AfterGUIInput TerrainWorldEditor::forward_spatial_input_event(Came
paint_brush_draw(position);
_gizmo->visible = true;
_gizmo->drawing = true;
_gizmo->position = position;
_gizmo->refresh_lines(_world);
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else {
_gizmo->visible = false;
_gizmo->redraw();
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}
@ -379,12 +448,19 @@ void TerrainWorldEditor::edit(TerrainWorld *p_world) {
return;
}
if (_gizmo.is_valid()) {
_gizmo->visible = false;
_gizmo->redraw();
}
_world = p_world;
if (!_world) {
return;
}
_gizmo = get_gizmo_from(_world);
_channel_type = _world->get_channel_index_info(TerrainWorld::CHANNEL_TYPE_INFO_TYPE);
_channel_isolevel = _world->get_channel_index_info(TerrainWorld::CHANNEL_TYPE_INFO_ISOLEVEL);
@ -794,9 +870,28 @@ void TerrainWorldEditor::_notification(int p_what) {
void TerrainWorldEditor::_node_removed(Node *p_node) {
if (p_node == _world) {
_world = NULL;
_gizmo.unref();
}
}
Ref<TerrainWorldGizmo> TerrainWorldEditor::get_gizmo_from(TerrainWorld *w) {
if (!w) {
return Ref<TerrainWorldGizmo>();
}
Vector<Ref<SpatialGizmo>> gizmos = w->get_gizmos();
for (int i = 0; i < gizmos.size(); ++i) {
Ref<TerrainWorldGizmo> g = gizmos[i];
if (g.is_valid()) {
return g;
}
}
return Ref<TerrainWorldGizmo>();
}
void TerrainWorldEditor::_on_surface_button_pressed() {
BaseButton *button = _surfaces_button_group->get_pressed_button();
@ -808,6 +903,9 @@ void TerrainWorldEditor::_on_surface_button_pressed() {
void TerrainWorldEditor::_on_tool_button_pressed() {
BaseButton *button = _tool_button_group->get_pressed_button();
_gizmo->visible = false;
_gizmo->redraw();
if (button) {
_previous_tool_mode = _tool_mode;
_tool_mode = static_cast<TerrainWorldEditorToolMode>(static_cast<int>(button->get_meta("tool_mode")));
@ -821,11 +919,13 @@ void TerrainWorldEditor::_on_tool_button_pressed() {
_paint_brush_tool_container->hide();
break;
case TOOL_MODE_PAINT_BRUSH:
_gizmo->size = _paint_brush_size;
_add_remove_tool_container->hide();
_isolevel_brush_tool_container->hide();
_paint_brush_tool_container->show();
break;
case TOOL_MODE_ISOLEVEL_BRUSH:
_gizmo->size = _isolevel_brush_size;
_add_remove_tool_container->hide();
_isolevel_brush_tool_container->show();
_paint_brush_tool_container->hide();
@ -956,6 +1056,12 @@ void TerrainWorldEditorPlugin::_notification(int p_what) {
}
void TerrainWorldEditorPlugin::edit(Object *p_object) {
TerrainWorld *ow = terrain_world_editor->get_edited_world();
if (p_object == ow) {
return;
}
terrain_world_editor->edit(Object::cast_to<TerrainWorld>(p_object));
}

View File

@ -37,6 +37,7 @@
#include "scene/gui/panel_container.h"
class TerrainWorldGizmo;
class TerrainWorld;
class SpatialEditorPlugin;
class HSlider;
@ -60,6 +61,8 @@ public:
};
public:
TerrainWorld *get_edited_world() { return _world; }
EditorPlugin::AfterGUIInput forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event);
void edit(TerrainWorld *p_world);
@ -72,6 +75,9 @@ public:
TerrainWorldEditor(EditorNode *p_editor);
~TerrainWorldEditor();
protected:
Ref<TerrainWorldGizmo> get_gizmo_from(TerrainWorld *w);
protected:
static void _bind_methods();
void _notification(int p_what);
@ -128,6 +134,7 @@ private:
private:
TerrainWorld *_world;
Ref<TerrainWorldGizmo> _gizmo;
int _selected_type;

View File

@ -31,13 +31,14 @@
#include "terrain_world_gizmo.h"
#include "core/math/math_defs.h"
#include "editor/editor_node.h"
#include "scene/3d/camera.h"
#include "scene/main/world.h"
#include "scene/resources/world_3d.h"
#include "servers/physics_server.h"
void TerrainWorldGizmo::set_visible(const bool visible) {
_visible = visible;
redraw();
}
#include "../world/terrain_world.h"
void TerrainWorldGizmo::set_editor_plugin(EditorPlugin *editor_plugin) {
_editor_plugin = editor_plugin;
@ -51,46 +52,85 @@ void TerrainWorldGizmo::set_handle(int index, bool secondary, Camera *camera, co
void TerrainWorldGizmo::redraw() {
clear();
if (!_visible) {
if (!visible) {
return;
}
if (!get_plugin().is_valid()) {
return;
}
/*
Ref<SpatialMaterial> handles_material = get_plugin()->get_material("handles", Ref<EditorSpatialGizmo>(this));
Ref<SpatialMaterial> material = get_plugin()->get_material("main", Ref<EditorSpatialGizmo>(this));
Ref<SpatialMaterial> seam_material = get_plugin()->get_material("seam", Ref<EditorSpatialGizmo>(this));
if (_lines.size() == 0) {
return;
}
_mesh_outline_generator->setup(_mdr);
Ref<SpatialMaterial> material;
if (selection_mode == SELECTION_MODE_EDGE) {
_mesh_outline_generator->generate_mark_edges(visual_indicator_outline, visual_indicator_handle);
} else if (selection_mode == SELECTION_MODE_FACE) {
_mesh_outline_generator->generate_mark_faces(visual_indicator_outline, visual_indicator_handle);
if (drawing) {
material = get_plugin()->get_material("drawing", Ref<EditorSpatialGizmo>(this));
} else {
_mesh_outline_generator->generate(visual_indicator_outline, visual_indicator_handle);
material = get_plugin()->get_material("main", Ref<EditorSpatialGizmo>(this));
}
if (visual_indicator_outline || visual_indicator_handle) {
add_lines(_mesh_outline_generator->lines, material, false);
}
if (visual_indicator_seam) {
add_lines(_mesh_outline_generator->seam_lines, seam_material, false);
}
*/
add_lines(_lines, material);
}
void TerrainWorldGizmo::apply() {
}
void TerrainWorldGizmo::refresh_lines(TerrainWorld *world) {
//Transform local_xform = world->get_global_transform().affine_inverse();
PhysicsDirectSpaceState *ss = world->get_world_3d()->get_direct_space_state();
Vector3 from;
Vector3 to;
PhysicsDirectSpaceState::RayResult res;
_lines.clear();
_points.clear();
float voxel_scale = world->get_voxel_scale();
Vector3 vsv = Vector3(voxel_scale, voxel_scale, voxel_scale);
for (int i = 0; i < 10; ++i) {
from = Vector3(Math::sin((Math_PI * 2.0 / 10.0) * (float)i) * size, 1000, Math::cos((Math_PI * 2.0 / 10.0) * (float)i) * size) * vsv;
to = Vector3(from.x, -from.y, from.z);
from += position;
to += position;
//from = local_xform.xform(from);
//to = local_xform.xform(to);
Vector3 p;
if (ss->intersect_ray(from, to, res)) {
p = res.position + res.normal.limit_length(0.1);
} else {
p = Vector3(from.x, 0, from.z);
}
_points.push_back(p);
}
for (int i = 1; i < _points.size(); ++i) {
_lines.push_back(_points[i - 1]);
_lines.push_back(_points[i]);
}
_lines.push_back(_points[_points.size() - 1]);
_lines.push_back(_points[0]);
redraw();
}
TerrainWorldGizmo::TerrainWorldGizmo() {
_editor_plugin = nullptr;
_undo_redo = nullptr;
_visible = false;
visible = false;
drawing = false;
size = 10;
}
TerrainWorldGizmo::~TerrainWorldGizmo() {

View File

@ -40,12 +40,16 @@ class MDREDMeshOutline;
class InputEvent;
class EditorPlugin;
class UndoRedo;
class TerrainWorld;
class TerrainWorldGizmo : public EditorSpatialGizmo {
GDCLASS(TerrainWorldGizmo, EditorSpatialGizmo);
public:
void set_visible(const bool visible);
bool visible;
bool drawing;
Vector3 position;
float size;
void set_editor_plugin(EditorPlugin *editor_plugin);
@ -53,19 +57,19 @@ public:
void redraw();
void apply();
void refresh_lines(TerrainWorld *world);
TerrainWorldGizmo();
~TerrainWorldGizmo();
PoolVector3Array _vertices;
PoolIntArray _indices;
EditorPlugin *_editor_plugin;
UndoRedo *_undo_redo;
bool _visible;
protected:
static void _bind_methods();
Vector<Vector3> _points;
Vector<Vector3> _lines;
};
#endif

View File

@ -65,8 +65,7 @@ TerrainWorldGizmoPlugin::TerrainWorldGizmoPlugin() {
plugin = nullptr;
create_material("main", Color(0.7, 0.7, 0.7));
create_material("seam", Color(1, 0, 0), false, true);
create_handle_material("handles");
create_material("drawing", Color(1, 0, 0));
}
TerrainWorldGizmoPlugin::~TerrainWorldGizmoPlugin() {

View File

@ -40,7 +40,6 @@ class TerrainWorldGizmoPlugin : public EditorSpatialGizmoPlugin {
GDCLASS(TerrainWorldGizmoPlugin, EditorSpatialGizmoPlugin);
public:
void _init();
String get_gizmo_name() const;
int get_priority() const;
bool is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx, bool p_secondary) const;