Implemented direct cursor and building coordinate setting

This commit is contained in:
2024-09-23 01:33:05 +03:00
parent 72bc6ade25
commit 7648beb507
2 changed files with 232 additions and 21 deletions

View File

@@ -3,6 +3,7 @@
#include <core/variant.h> #include <core/variant.h>
#include <core/os/time.h> #include <core/os/time.h>
#include <scene/gui/option_button.h> #include <scene/gui/option_button.h>
#include <scene/gui/line_edit.h>
#include <scene/main/viewport.h> #include <scene/main/viewport.h>
#include <scene/3d/camera.h> #include <scene/3d/camera.h>
#include <modules/voxel/terrain/voxel_lod_terrain.h> #include <modules/voxel/terrain/voxel_lod_terrain.h>
@@ -13,6 +14,194 @@
#include "buildings_data.h" #include "buildings_data.h"
#include "buildings_editor.h" #include "buildings_editor.h"
class HandlePositionSetting : public Object {
GDCLASS(HandlePositionSetting, Object)
BuildingsEditor *editor;
int old_mode;
public:
HandlePositionSetting(BuildingsEditor *editor)
: Object()
, editor(editor)
, old_mode(-1)
{
SceneTree::get_singleton()->connect("idle_frame", this,
"handle_update");
Button *set_cursor_position = editor->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->connect("pressed", this,
"handle_set_cursor");
Button *set_building_position = editor->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->connect("pressed", this,
"handle_set_building");
EditorEvent::get_singleton()->event.add_listener(
this, &HandlePositionSetting::handle_event);
int building = editor->get_selected_building();
if (building >= 0) {
Vector3 building_pos =
editor->get_selected_building_xform().origin;
}
}
virtual ~HandlePositionSetting()
{
EditorEvent::get_singleton()->event.remove_listener(
this, &HandlePositionSetting::handle_event);
Button *set_building_position = editor->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->disconnect("pressed", this,
"handle_set_building");
Button *set_cursor_position = editor->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->disconnect("pressed", this,
"handle_set_cursor");
SceneTree::get_singleton()->disconnect("idle_frame", this,
"handle_update");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("handle_update"),
&HandlePositionSetting::handle_update);
ClassDB::bind_method(D_METHOD("handle_set_cursor"),
&HandlePositionSetting::handle_set_cursor);
ClassDB::bind_method(
D_METHOD("handle_set_building"),
&HandlePositionSetting::handle_set_building);
}
private:
void handle_event(const String &event, const Array &args)
{
if (event == "buildings_building_cursor_moved") {
Vector3 position = args[0];
LineEdit *cursor_x = editor->get_as_node<LineEdit>(
"%building_cursor_x");
LineEdit *cursor_y = editor->get_as_node<LineEdit>(
"%building_cursor_y");
LineEdit *cursor_z = editor->get_as_node<LineEdit>(
"%building_cursor_z");
cursor_x->set_text(String::num(position.x));
cursor_y->set_text(String::num(position.y));
cursor_z->set_text(String::num(position.z));
} else if (event == "buildings_building_selected" ||
event == "buildings_building_moved" ||
event == "buildings_building_rotated") {
LineEdit *position_x = editor->get_as_node<LineEdit>(
"%building_position_x");
LineEdit *position_y = editor->get_as_node<LineEdit>(
"%building_position_y");
LineEdit *position_z = editor->get_as_node<LineEdit>(
"%building_position_z");
Transform xform = editor->get_selected_building_xform();
position_x->set_text(String::num(xform.origin.x));
position_y->set_text(String::num(xform.origin.y));
position_z->set_text(String::num(xform.origin.z));
}
}
void handle_set_cursor()
{
LineEdit *cursor_x =
editor->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
editor->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
editor->get_as_node<LineEdit>("%building_cursor_z");
Vector3 position;
position.x = cursor_x->get_text().to_float();
position.y = cursor_y->get_text().to_float();
position.z = cursor_z->get_text().to_float();
editor->set_cursor_position(position);
}
void handle_set_building()
{
LineEdit *position_x =
editor->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
editor->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
editor->get_as_node<LineEdit>("%building_position_z");
Transform xform = editor->get_selected_building_xform();
xform.origin.x = position_x->get_text().to_float();
xform.origin.y = position_y->get_text().to_float();
xform.origin.z = position_z->get_text().to_float();
int id = editor->get_selected_building();
Array args;
args.push_back(id);
args.push_back(xform);
int mode = editor->get_buildings_editor_mode();
if (mode == 1 || mode == 2)
editor->set_cursor_position(xform.origin);
editor->emit("run_update_building_transform", args);
}
void handle_update()
{
// TODO: handle selection
int i;
int mode = editor->get_buildings_editor_mode();
LineEdit *cursor_x =
editor->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
editor->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
editor->get_as_node<LineEdit>("%building_cursor_z");
LineEdit *cursor_le[] = { cursor_x, cursor_y, cursor_z };
Button *set_cursor_position = editor->get_as_node<Button>(
"%buildings_set_cursor_position");
LineEdit *position_x =
editor->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
editor->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
editor->get_as_node<LineEdit>("%building_position_z");
LineEdit *position_le[] = { position_x, position_y,
position_z };
Button *set_building_position = editor->get_as_node<Button>(
"%buildings_set_building_position");
int sz_cursor = (int)(sizeof(cursor_le) / sizeof(cursor_le[0]));
int sz_position =
(int)(sizeof(position_le) / sizeof(position_le[0]));
if (mode != old_mode) {
switch (mode) {
case 0: // select
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(false);
set_building_position->set_disabled(true);
break;
case 1: // move
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 2: // rotate
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 3: // create
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(true);
set_cursor_position->set_disabled(false);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
}
old_mode = mode;
}
}
};
class HandleChangeBuildingType : public Object { class HandleChangeBuildingType : public Object {
GDCLASS(HandleChangeBuildingType, Object) GDCLASS(HandleChangeBuildingType, Object)
BuildingsEditor *editor; BuildingsEditor *editor;
@@ -168,6 +357,7 @@ void BuildingsEditor::activate()
this, "%buildings_create_building", "create_building", args))); this, "%buildings_create_building", "create_building", args)));
ui_handlers.push_back(memnew(HandleChangeBuildingType(this))); ui_handlers.push_back(memnew(HandleChangeBuildingType(this)));
ui_handlers.push_back(memnew(HandleDeleteButton(this))); ui_handlers.push_back(memnew(HandleDeleteButton(this)));
ui_handlers.push_back(memnew(HandlePositionSetting(this)));
int i; int i;
for (i = 0; i < (int)ui_handlers.size(); i++) for (i = 0; i < (int)ui_handlers.size(); i++)
assert(ui_handlers[i]); assert(ui_handlers[i]);
@@ -223,6 +413,14 @@ void BuildingsEditor::event_handler(const String &event, const Array &args)
} }
} else if (event == "result:get_building_types") { } else if (event == "result:get_building_types") {
/* TODO: replace with direct data access */ /* TODO: replace with direct data access */
} else if (event == "run_update_building_transform") {
selected_building_xform = args[1];
editor->editor_command("update_building_transform", args);
if (get_buildings_editor_mode() == 2 /* rotate */) {
/* move rot cursor too */
get_as_node<Spatial>("%building_rot_cursor")
->set_global_transform(selected_building_xform);
}
} }
print_line("buildings::" + event); print_line("buildings::" + event);
} }
@@ -238,8 +436,8 @@ void BuildingsEditor::handle_create_building()
if (index >= 0) { if (index >= 0) {
const String &item = building_type->get_item_text(index); const String &item = building_type->get_item_text(index);
Array args; Array args;
Transform xform = get_as_node<Spatial>("%building_cursor") Transform xform;
->get_global_transform(); xform.origin = get_cursor_position();
Dictionary building_data; Dictionary building_data;
/* FIXME: calculate AABBs as in previous editor */ /* FIXME: calculate AABBs as in previous editor */
String building_xform = to_string<Transform>(xform); String building_xform = to_string<Transform>(xform);
@@ -329,13 +527,10 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
newpos)); newpos));
editor->editor_command("update_building_transform", editor->editor_command("update_building_transform",
args); args);
Spatial *cursor = set_cursor_position(newpos);
get_as_node<Spatial>("%building_cursor");
Transform orig_pos = cursor->get_global_transform();
orig_pos.origin = newpos;
cursor->set_global_transform(orig_pos);
selected_building_xform = Transform( selected_building_xform = Transform(
selected_building_xform.basis, newpos); selected_building_xform.basis, newpos);
emit("buildings_building_moved", Array());
} break; } break;
case 2: { case 2: {
/* rotate */ /* rotate */
@@ -352,6 +547,7 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
selected_building_xform = xform; selected_building_xform = xform;
get_as_node<Spatial>("%building_rot_cursor") get_as_node<Spatial>("%building_rot_cursor")
->set_global_transform(xform); ->set_global_transform(xform);
emit("buildings_building_rotated", Array());
} break; } break;
case 3: { /* create */ case 3: { /* create */
print_verbose("create: " + (proj.operator String())); print_verbose("create: " + (proj.operator String()));
@@ -362,9 +558,7 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
->get_generator(); ->get_generator();
float h = gen->get_height_full(newpos); float h = gen->get_height_full(newpos);
newpos.y = h; newpos.y = h;
Transform xform(Basis(), newpos); set_cursor_position(newpos);
get_as_node<Spatial>("%building_cursor")
->set_global_transform(xform);
} break; } break;
} }
} }
@@ -420,6 +614,7 @@ void BuildingsEditor::mouse_press(const Vector2 &position)
selected_building_xform = xform; selected_building_xform = xform;
get_as_node<Spatial>("%building_rot_cursor") get_as_node<Spatial>("%building_rot_cursor")
->set_global_transform(xform); ->set_global_transform(xform);
emit("buildings_building_rotated", Array());
} break; } break;
/* TODO: deduplicate */ /* TODO: deduplicate */
case 3: { /* create */ case 3: { /* create */
@@ -431,15 +626,34 @@ void BuildingsEditor::mouse_press(const Vector2 &position)
->get_generator(); ->get_generator();
float h = gen->get_height_full(newpos); float h = gen->get_height_full(newpos);
newpos.y = h; newpos.y = h;
Transform xform(Basis(), newpos); set_cursor_position(newpos);
get_as_node<Spatial>("%building_cursor")->show();
get_as_node<Spatial>("%building_cursor")
->set_global_transform(xform);
} break; } break;
} }
} }
} }
void BuildingsEditor::set_cursor_position(const Vector3 &position)
{
Spatial *cursor = get_as_node<Spatial>("%building_cursor");
if (!cursor->is_visible())
cursor->show();
Transform xform = cursor->get_global_transform();
if (!xform.origin.is_equal_approx(position)) {
xform.origin = position;
cursor->set_global_transform(xform);
Array args;
args.push_back(position);
emit("buildings_building_cursor_moved", args);
}
}
Vector3 BuildingsEditor::get_cursor_position() const
{
const Spatial *cursor = get_as_node<Spatial>("%building_cursor");
Transform xform = cursor->get_global_transform();
return xform.origin;
}
int BuildingsEditor::get_buildings_editor_mode() const int BuildingsEditor::get_buildings_editor_mode() const
{ {
const OptionButton *buildings_edit_mode = const OptionButton *buildings_edit_mode =
@@ -519,14 +733,9 @@ void BuildingsEditor::select_building(const Transform &xform, int id,
Button *delete_button = Button *delete_button =
get_as_node<Button>("%buildings_delete_building"); get_as_node<Button>("%buildings_delete_building");
delete_button->show(); delete_button->show();
emit("buildings_building_selected", Array());
} }
Spatial *cursor = get_as_node<Spatial>("%building_cursor"); set_cursor_position(xform.origin);
/* Show cursor and change cursor position */
if (!cursor->is_visible())
cursor->show();
Transform orig_xform = cursor->get_global_transform();
orig_xform.origin = xform.origin;
cursor->set_global_transform(orig_xform);
} }
void BuildingsEditor::editor_command(const String &command, const Array &args) void BuildingsEditor::editor_command(const String &command, const Array &args)

View File

@@ -19,6 +19,8 @@ public:
void update(float delta); void update(float delta);
void mouse_drag(const Vector2 &position); void mouse_drag(const Vector2 &position);
void mouse_press(const Vector2 &position); void mouse_press(const Vector2 &position);
void set_cursor_position(const Vector3 &position);
Vector3 get_cursor_position() const;
int get_buildings_editor_mode() const; int get_buildings_editor_mode() const;
virtual ~BuildingsEditor(); virtual ~BuildingsEditor();
int get_selected_building() const; int get_selected_building() const;