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/os/time.h>
#include <scene/gui/option_button.h>
#include <scene/gui/line_edit.h>
#include <scene/main/viewport.h>
#include <scene/3d/camera.h>
#include <modules/voxel/terrain/voxel_lod_terrain.h>
@@ -13,6 +14,194 @@
#include "buildings_data.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 {
GDCLASS(HandleChangeBuildingType, Object)
BuildingsEditor *editor;
@@ -168,6 +357,7 @@ void BuildingsEditor::activate()
this, "%buildings_create_building", "create_building", args)));
ui_handlers.push_back(memnew(HandleChangeBuildingType(this)));
ui_handlers.push_back(memnew(HandleDeleteButton(this)));
ui_handlers.push_back(memnew(HandlePositionSetting(this)));
int i;
for (i = 0; i < (int)ui_handlers.size(); 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") {
/* 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);
}
@@ -238,8 +436,8 @@ void BuildingsEditor::handle_create_building()
if (index >= 0) {
const String &item = building_type->get_item_text(index);
Array args;
Transform xform = get_as_node<Spatial>("%building_cursor")
->get_global_transform();
Transform xform;
xform.origin = get_cursor_position();
Dictionary building_data;
/* FIXME: calculate AABBs as in previous editor */
String building_xform = to_string<Transform>(xform);
@@ -329,13 +527,10 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
newpos));
editor->editor_command("update_building_transform",
args);
Spatial *cursor =
get_as_node<Spatial>("%building_cursor");
Transform orig_pos = cursor->get_global_transform();
orig_pos.origin = newpos;
cursor->set_global_transform(orig_pos);
set_cursor_position(newpos);
selected_building_xform = Transform(
selected_building_xform.basis, newpos);
emit("buildings_building_moved", Array());
} break;
case 2: {
/* rotate */
@@ -352,6 +547,7 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
selected_building_xform = xform;
get_as_node<Spatial>("%building_rot_cursor")
->set_global_transform(xform);
emit("buildings_building_rotated", Array());
} break;
case 3: { /* create */
print_verbose("create: " + (proj.operator String()));
@@ -362,9 +558,7 @@ void BuildingsEditor::mouse_drag(const Vector2 &position)
->get_generator();
float h = gen->get_height_full(newpos);
newpos.y = h;
Transform xform(Basis(), newpos);
get_as_node<Spatial>("%building_cursor")
->set_global_transform(xform);
set_cursor_position(newpos);
} break;
}
}
@@ -420,6 +614,7 @@ void BuildingsEditor::mouse_press(const Vector2 &position)
selected_building_xform = xform;
get_as_node<Spatial>("%building_rot_cursor")
->set_global_transform(xform);
emit("buildings_building_rotated", Array());
} break;
/* TODO: deduplicate */
case 3: { /* create */
@@ -431,15 +626,34 @@ void BuildingsEditor::mouse_press(const Vector2 &position)
->get_generator();
float h = gen->get_height_full(newpos);
newpos.y = h;
Transform xform(Basis(), newpos);
get_as_node<Spatial>("%building_cursor")->show();
get_as_node<Spatial>("%building_cursor")
->set_global_transform(xform);
set_cursor_position(newpos);
} 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
{
const OptionButton *buildings_edit_mode =
@@ -519,14 +733,9 @@ void BuildingsEditor::select_building(const Transform &xform, int id,
Button *delete_button =
get_as_node<Button>("%buildings_delete_building");
delete_button->show();
emit("buildings_building_selected", Array());
}
Spatial *cursor = get_as_node<Spatial>("%building_cursor");
/* 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);
set_cursor_position(xform.origin);
}
void BuildingsEditor::editor_command(const String &command, const Array &args)

View File

@@ -19,6 +19,8 @@ public:
void update(float delta);
void mouse_drag(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;
virtual ~BuildingsEditor();
int get_selected_building() const;