Implemented direct cursor and building coordinate setting
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user