Implemented structure relocation
This commit is contained in:
@@ -30,6 +30,7 @@ void StreamWorld::read_buildings_json(const String &buildings_path)
|
||||
while (e) {
|
||||
struct building b;
|
||||
String key = e->get();
|
||||
b.key = key;
|
||||
b.id = json[key].get("id");
|
||||
if (b.id == "empty") {
|
||||
e = e->next();
|
||||
@@ -277,6 +278,67 @@ void StreamWorld::update_items()
|
||||
|
||||
void StreamWorld::run_command(const String &command, const Array &args)
|
||||
{
|
||||
if (command == "get_closest_building") {
|
||||
if (args.size() == 0) {
|
||||
print_error("bad command: not enough args: " + command);
|
||||
return;
|
||||
}
|
||||
const Transform &xform = args[0];
|
||||
int i;
|
||||
float dst = Math_INF;
|
||||
Transform ret;
|
||||
String rkey;
|
||||
int id = -1;
|
||||
for (i = 0; i < (int)buildings.size(); i++) {
|
||||
Vector3 o = xform.origin;
|
||||
Vector3 m = buildings[i].xform.origin;
|
||||
float mdst = o.distance_squared_to(m);
|
||||
if (dst > mdst) {
|
||||
ret = buildings[i].xform;
|
||||
dst = mdst;
|
||||
rkey = buildings[i].key;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
Array ret_data;
|
||||
ret_data.resize(4);
|
||||
ret_data[0] = ret;
|
||||
ret_data[1] = dst;
|
||||
ret_data[2] = rkey;
|
||||
ret_data[3] = id;
|
||||
emit_signal("command_result", command, ret_data);
|
||||
} else if (command == "get_building_id_for_key") {
|
||||
if (args.size() == 0) {
|
||||
print_error("bad command: not enough args: " + command);
|
||||
return;
|
||||
}
|
||||
String key = args[1];
|
||||
Array ret_data;
|
||||
ret_data.resize(1);
|
||||
int id = -1, i;
|
||||
for (i = 0; i < (int)buildings.size(); i++)
|
||||
if (buildings[i].key == key) {
|
||||
id = i;
|
||||
break;
|
||||
}
|
||||
ret_data[0] = id;
|
||||
emit_signal("command_result", command, ret_data);
|
||||
} else if (command == "update_building_transform") {
|
||||
if (args.size() == 0) {
|
||||
print_error("bad command: not enough args: " + command);
|
||||
return;
|
||||
}
|
||||
int id = args[0];
|
||||
if (id < 0 || id >= (int)buildings.size())
|
||||
return;
|
||||
String key = buildings[id].key;
|
||||
buildings[id].xform == args[1];
|
||||
Spatial *bnode = Object::cast_to<Spatial>(item_nodes[id]);
|
||||
bnode->set_global_transform(args[1]);
|
||||
VariantWriter::write_to_string(buildings[id].xform, key);
|
||||
buildings[id].key = key;
|
||||
} else
|
||||
print_error("No command " + command);
|
||||
}
|
||||
|
||||
void StreamWorld::_notification(int which)
|
||||
@@ -287,6 +349,8 @@ void StreamWorld::_notification(int which)
|
||||
case NOTIFICATION_EXIT_WORLD:
|
||||
break;
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
break;
|
||||
if (initialized) {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
current_scene = Object::cast_to<Node>(this);
|
||||
@@ -303,6 +367,8 @@ void StreamWorld::_notification(int which)
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
break;
|
||||
case NOTIFICATION_PROCESS: {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
break;
|
||||
update_view();
|
||||
const String *key = scenes.next(nullptr);
|
||||
while (key) {
|
||||
@@ -337,6 +403,9 @@ void StreamWorld::_bind_methods()
|
||||
&StreamWorld::viewer_dead);
|
||||
ClassDB::bind_method(D_METHOD("run_command", "command", "args"),
|
||||
&StreamWorld::run_command);
|
||||
ADD_SIGNAL(MethodInfo("command_result",
|
||||
PropertyInfo(Variant::STRING, "result_name"),
|
||||
PropertyInfo(Variant::ARRAY, "args")));
|
||||
}
|
||||
|
||||
StreamWorld::StreamWorld()
|
||||
@@ -396,4 +465,4 @@ void StreamWorld::cleanup()
|
||||
StreamWorld::~StreamWorld()
|
||||
{
|
||||
RoadProcessing::cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ private:
|
||||
Node *current_scene;
|
||||
struct building {
|
||||
String id;
|
||||
String key;
|
||||
Transform xform;
|
||||
AABB aabb;
|
||||
};
|
||||
@@ -57,10 +58,11 @@ private:
|
||||
void unload_building(int id);
|
||||
void request_item(int type, int item);
|
||||
void update_items();
|
||||
void run_command(const String &command, const Array &args);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void run_command(const String &command, const Array &args);
|
||||
StreamWorld();
|
||||
~StreamWorld();
|
||||
static void cleanup();
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include <core/object.h>
|
||||
#include <core/engine.h>
|
||||
#include <scene/gui/control.h>
|
||||
#include <scene/gui/box_container.h>
|
||||
#include <scene/gui/button.h>
|
||||
#include <scene/scene_string_names.h>
|
||||
#include "world_editor.h"
|
||||
|
||||
WorldEditor::WorldEditor()
|
||||
: Spatial()
|
||||
, stream_world(nullptr)
|
||||
, editor_menu(nullptr)
|
||||
, current_mode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,9 +73,16 @@ static std::unordered_map<String, int, StringHasher> modes = {
|
||||
};
|
||||
void WorldEditor::tools_button(const String &button)
|
||||
{
|
||||
Array change;
|
||||
change.resize(2);
|
||||
print_line("tools_button: " + button);
|
||||
if (modes.find(button) == modes.end())
|
||||
goto end;
|
||||
if (current_mode == modes[button])
|
||||
goto end;
|
||||
change[0] = current_mode;
|
||||
change[1] = modes[button];
|
||||
emit_signal("editor_event", "mode_change_pre", change);
|
||||
switch (modes[button]) {
|
||||
case MODE_BUILDINGS:
|
||||
mode_buildings();
|
||||
@@ -90,82 +100,89 @@ void WorldEditor::tools_button(const String &button)
|
||||
mode_npc();
|
||||
break;
|
||||
}
|
||||
emit_signal("editor_event", "mode_change_post", change);
|
||||
current_mode = modes[button];
|
||||
end:;
|
||||
}
|
||||
|
||||
#define CREATE_TOOLS_BUTTON(bname, btext) \
|
||||
{ \
|
||||
Vector<Variant> binds; \
|
||||
binds.push_back(#bname); \
|
||||
Button *bname = memnew(Button); \
|
||||
bname->set_name(#bname); \
|
||||
bname->set_text(btext); \
|
||||
bname->set_custom_minimum_size(Vector2(188, 16)); \
|
||||
bname->connect("pressed", this, "tools_button", binds); \
|
||||
tools->add_child(bname); \
|
||||
bname->update(); \
|
||||
tools->update(); \
|
||||
}
|
||||
void WorldEditor::create_menu()
|
||||
void WorldEditor::editor_command(const String &command, const Array &args)
|
||||
{
|
||||
editor_menu = memnew(Control);
|
||||
editor_menu->set_name("menu");
|
||||
editor_menu->set_anchor(MARGIN_LEFT, 1.0f);
|
||||
editor_menu->set_anchor(MARGIN_RIGHT, 1.0f);
|
||||
editor_menu->set_anchor(MARGIN_BOTTOM, 1.0f);
|
||||
editor_menu->set_anchor(MARGIN_TOP, 0.0f);
|
||||
editor_menu->update();
|
||||
VBoxContainer *tools = memnew(VBoxContainer);
|
||||
Vector2 min_size = tools->get_minimum_size();
|
||||
min_size.x = 200.0f;
|
||||
min_size.y = 400.0f;
|
||||
tools->set_custom_minimum_size(min_size);
|
||||
tools->set_name("tools");
|
||||
tools->set_anchor_and_margin(MARGIN_LEFT, 1.0f, -210.0f);
|
||||
tools->set_anchor_and_margin(MARGIN_RIGHT, 1.0f, 0.0f);
|
||||
tools->set_anchor_and_margin(MARGIN_BOTTOM, 1.0f, 0.0f);
|
||||
tools->set_anchor_and_margin(MARGIN_TOP, 0.0f, 0.0f);
|
||||
tools->set_mouse_filter(Control::MOUSE_FILTER_STOP);
|
||||
editor_menu->add_child(tools);
|
||||
|
||||
CREATE_TOOLS_BUTTON(select_buildings, "Select Buildings");
|
||||
CREATE_TOOLS_BUTTON(select_navigation, "Select Navigation");
|
||||
CREATE_TOOLS_BUTTON(select_poi, "Select POI");
|
||||
CREATE_TOOLS_BUTTON(select_road_lines, "Select Road Lines");
|
||||
CREATE_TOOLS_BUTTON(select_npc, "Select NPC");
|
||||
editor_menu->update();
|
||||
tools->update();
|
||||
editor_menu->update();
|
||||
tools->update();
|
||||
print_line("Created menu");
|
||||
print_line("running command: " + command);
|
||||
if (command.begins_with("select_") &&
|
||||
modes.find(command) != modes.end()) {
|
||||
tools_button(command);
|
||||
return;
|
||||
} else if (command == "get_closest_building") {
|
||||
if (stream_world) {
|
||||
stream_world->run_command(command, args);
|
||||
}
|
||||
} else if (command == "update_building_transform") {
|
||||
if (stream_world) {
|
||||
stream_world->run_command(command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control *WorldEditor::get_editor_menu()
|
||||
int WorldEditor::get_current_mode() const
|
||||
{
|
||||
if (!is_inside_tree())
|
||||
return nullptr;
|
||||
if (!editor_menu)
|
||||
create_menu();
|
||||
return editor_menu;
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
StreamWorld *WorldEditor::get_stream_world()
|
||||
{
|
||||
return stream_world;
|
||||
}
|
||||
|
||||
void WorldEditor::world_command_result(const String &what, const Array &data)
|
||||
{
|
||||
print_line("what: " + what);
|
||||
emit_signal("editor_event", "result:" + what, data);
|
||||
}
|
||||
|
||||
void WorldEditor::_notification(int which)
|
||||
{
|
||||
switch (which) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
Control *c = get_editor_menu();
|
||||
if (c)
|
||||
add_child(c);
|
||||
Node *base = get_parent();
|
||||
int count = base->get_child_count();
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
Node *node = base->get_child(i);
|
||||
StreamWorld *sw = Object::cast_to<StreamWorld>(node);
|
||||
if (sw && !stream_world &&
|
||||
!Engine::get_singleton()->is_editor_hint()) {
|
||||
stream_world = sw;
|
||||
sw->connect(SceneStringNames::get_singleton()
|
||||
->tree_exiting,
|
||||
this, "world_exited");
|
||||
sw->connect("command_result", this,
|
||||
"world_command_result");
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
if (editor_menu)
|
||||
editor_menu->queue_delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldEditor::world_exited()
|
||||
{
|
||||
stream_world = nullptr;
|
||||
}
|
||||
|
||||
void WorldEditor::_bind_methods()
|
||||
{
|
||||
ClassDB::bind_method(D_METHOD("tools_button", "button"),
|
||||
&WorldEditor::tools_button);
|
||||
ClassDB::bind_method(D_METHOD("editor_command", "command", "args"),
|
||||
&WorldEditor::editor_command);
|
||||
ClassDB::bind_method(D_METHOD("get_current_mode"),
|
||||
&WorldEditor::get_current_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_stream_world"),
|
||||
&WorldEditor::get_stream_world);
|
||||
ClassDB::bind_method(D_METHOD("world_exited"),
|
||||
&WorldEditor::world_exited);
|
||||
ClassDB::bind_method(D_METHOD("world_command_result", "what", "data"),
|
||||
&WorldEditor::world_command_result);
|
||||
ADD_SIGNAL(MethodInfo("editor_event",
|
||||
PropertyInfo(Variant::STRING, "event_name"),
|
||||
PropertyInfo(Variant::ARRAY, "args")));
|
||||
}
|
||||
|
||||
@@ -13,12 +13,18 @@ protected:
|
||||
void mode_poi();
|
||||
void mode_road_lines();
|
||||
void mode_npc();
|
||||
void tools_button(const String &which);
|
||||
void create_menu();
|
||||
Control *get_editor_menu();
|
||||
void tools_button(const String &button);
|
||||
void editor_command(const String &command, const Array &args);
|
||||
int get_current_mode() const;
|
||||
StreamWorld *get_stream_world();
|
||||
void world_command_result(const String &what, const Array &data);
|
||||
void _notification(int which);
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
void world_exited();
|
||||
int current_mode;
|
||||
|
||||
public:
|
||||
WorldEditor();
|
||||
~WorldEditor();
|
||||
|
||||
Reference in New Issue
Block a user