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