diff --git a/godot/astream/blayout.conf b/godot/astream/blayout.conf index 46aafdd..450710c 100644 --- a/godot/astream/blayout.conf +++ b/godot/astream/blayout.conf @@ -3,7 +3,7 @@ element_types={ "corner1": { "name": "corner1", -"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 7.54979e-08, 0, -1, 0, 1, 0, 1, 0, 7.54979e-08, 2, 0, -4 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] +"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 7.54979e-08, 0, -1, 0, 1, 0, 1, 0, 7.54979e-08, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] }, "e1": { "name": "e1", @@ -15,11 +15,11 @@ element_types={ }, "just_floor": { "name": "just_floor", -"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] +"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] }, "side_wall": { "name": "side_wall", -"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] +"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ] } } elements={ @@ -384,9 +384,9 @@ grid_layouts={ "index": 78, "rotation": 0 }, { -"element": "empty", +"element": "corner", "index": 79, -"rotation": 0 +"rotation": 1 }, { "element": "empty", "index": 80, @@ -1159,11 +1159,11 @@ grid_layouts={ "index": 28, "rotation": 0 }, { -"element": "empty", +"element": "normal_floor", "index": 29, "rotation": 0 }, { -"element": "empty", +"element": "normal_floor", "index": 30, "rotation": 0 }, { @@ -1359,9 +1359,9 @@ grid_layouts={ "index": 78, "rotation": 0 }, { -"element": "empty", +"element": "corner", "index": 79, -"rotation": 0 +"rotation": 1 }, { "element": "empty", "index": 80, @@ -1432,13 +1432,13 @@ grid_layouts={ "index": 15, "rotation": 0 }, { -"element": "empty", +"element": "side_wall", "index": 16, -"rotation": 0 +"rotation": 2 }, { -"element": "empty", +"element": "corner", "index": 17, -"rotation": 0 +"rotation": 2 }, { "element": "empty", "index": 18, @@ -1504,9 +1504,9 @@ grid_layouts={ "index": 33, "rotation": 0 }, { -"element": "empty", +"element": "normal_floor", "index": 34, -"rotation": 0 +"rotation": 2 }, { "element": "empty", "index": 35, @@ -1612,9 +1612,9 @@ grid_layouts={ "index": 60, "rotation": 0 }, { -"element": "empty", +"element": "side_wall", "index": 61, -"rotation": 0 +"rotation": 1 }, { "element": "empty", "index": 62, @@ -1646,15 +1646,15 @@ grid_layouts={ }, { "element": "empty", "index": 69, -"rotation": 0 +"rotation": 1 }, { -"element": "empty", +"element": "side_window", "index": 70, -"rotation": 0 +"rotation": 1 }, { "element": "empty", "index": 71, -"rotation": 0 +"rotation": 3 }, { "element": "corner", "index": 72, @@ -1684,9 +1684,9 @@ grid_layouts={ "index": 78, "rotation": 0 }, { -"element": "empty", +"element": "corner", "index": 79, -"rotation": 0 +"rotation": 1 }, { "element": "empty", "index": 80, diff --git a/godot/main/building_layout_editor.tscn b/godot/main/building_layout_editor.tscn index d9e92cd..36eff6d 100644 --- a/godot/main/building_layout_editor.tscn +++ b/godot/main/building_layout_editor.tscn @@ -330,43 +330,89 @@ columns = 2 unique_name_in_owner = true margin_top = 719.0 margin_right = 314.0 -margin_bottom = 847.0 +margin_bottom = 999.0 [node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/layout_editor"] margin_left = 7.0 margin_top = 7.0 margin_right = 307.0 -margin_bottom = 121.0 +margin_bottom = 273.0 [node name="grid_elements" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] unique_name_in_owner = true margin_right = 300.0 margin_bottom = 20.0 -[node name="clear_grid_cell" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"] +[node name="select_rotation" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] unique_name_in_owner = true margin_top = 24.0 margin_right = 300.0 margin_bottom = 44.0 -text = "Clear cell" +text = "0" +items = [ "0", null, false, 0, null, "90", null, false, 1, null, "180", null, false, 2, null, "270", null, false, 3, null ] +selected = 0 -[node name="Label" type="Label" parent="VBoxContainer/layout_editor/VBoxContainer"] +[node name="clear_grid_cell" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true margin_top = 48.0 margin_right = 300.0 -margin_bottom = 62.0 +margin_bottom = 68.0 +text = "Clear cell" + +[node name="grow_cell_button" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true +margin_top = 72.0 +margin_right = 300.0 +margin_bottom = 92.0 +text = "Grow" + +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/layout_editor/VBoxContainer"] +margin_top = 96.0 +margin_right = 300.0 +margin_bottom = 100.0 + +[node name="grid_elements_corner" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true +margin_top = 104.0 +margin_right = 300.0 +margin_bottom = 124.0 + +[node name="grid_elements_side" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true +margin_top = 128.0 +margin_right = 300.0 +margin_bottom = 148.0 + +[node name="grid_elements_floor" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true +margin_top = 152.0 +margin_right = 300.0 +margin_bottom = 172.0 + +[node name="make_room_button" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"] +unique_name_in_owner = true +margin_top = 176.0 +margin_right = 300.0 +margin_bottom = 196.0 +text = "Make Room" + +[node name="Label" type="Label" parent="VBoxContainer/layout_editor/VBoxContainer"] +margin_top = 200.0 +margin_right = 300.0 +margin_bottom = 214.0 text = "Level" [node name="level_value" type="SpinBox" parent="VBoxContainer/layout_editor/VBoxContainer"] unique_name_in_owner = true -margin_top = 66.0 +margin_top = 218.0 margin_right = 300.0 -margin_bottom = 90.0 +margin_bottom = 242.0 [node name="layout_selector" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"] unique_name_in_owner = true -margin_top = 94.0 +margin_top = 246.0 margin_right = 300.0 -margin_bottom = 114.0 +margin_bottom = 266.0 [node name="BuildingLayoutEditor" type="BuildingLayoutEditor" parent="."] source = ExtResource( 2 ) @@ -375,7 +421,7 @@ source = ExtResource( 2 ) unique_name_in_owner = true [node name="refcube" type="MeshInstance" parent="refcube"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 4, -2 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0 ) mesh = SubResource( 3 ) skeleton = NodePath("../..") diff --git a/src/modules/stream/buildings/building_layout_editor.cpp b/src/modules/stream/buildings/building_layout_editor.cpp index a88a124..9a6d2b4 100644 --- a/src/modules/stream/buildings/building_layout_editor.cpp +++ b/src/modules/stream/buildings/building_layout_editor.cpp @@ -16,718 +16,9 @@ #include #include #include "editor_event.h" +#include "element_data.h" #include "building_layout_editor.h" -template T *get_as_node(const String &path) -{ - Node *scene; - if (Engine::get_singleton()->is_editor_hint()) - scene = EditorNode::get_singleton()->get_edited_scene(); - else - scene = SceneTree::get_singleton()->get_current_scene(); - assert(scene); - Node *node = scene->get_node(NodePath(path)); - if (!node) - print_error("Failed to get " + path); - assert(node); - T *ret = Object::cast_to(node); - if (!ret) - print_error("Failed to assign " + path); - assert(ret); - return ret; -} - -template -void select_control_item(const String &path, const String &item) -{ - int i; - T *ctl = get_as_node(path); - int selected = -1; - for (i = 0; i < ctl->get_item_count(); i++) - if (ctl->get_item_text(i) == item) { - selected = i; - break; - } - if (selected >= 0) { - ctl->select(selected); - print_line("selected: " + item); - } -} -template void select_control_item(T *ctl, const String &item) -{ - int i; - int selected = -1; - for (i = 0; i < ctl->get_item_count(); i++) - if (ctl->get_item_text(i) == item) { - selected = i; - break; - } - if (selected >= 0) { - ctl->select(selected); - print_line("selected: " + item); - } -} - -#define ELEMENT_SOCKETS 16 -class ElementData { - flecs::world ecs; - static ElementData *singleton; - -public: - static ElementData *get_singleton() - { - if (!singleton) - singleton = memnew(ElementData); - return singleton; - } - static void cleanup() - { - if (singleton) - memdelete(singleton); - } - struct grid_element_type { - String name; - Transform sockets[ELEMENT_SOCKETS]; - }; - struct grid_element { - String name; - String type; - String mesh_names[ELEMENT_SOCKETS]; - }; - int grid_step{ 4 }; - int grid_size{ 9 }; - struct grid_cell { - String element; - int rotation; - }; - struct grid_layouts {}; - struct grid_layout {}; - struct grid_layout_base { - int floor_count; - }; - struct grid_layout_exterior {}; - struct grid_layout_interior {}; - struct grid_floor {}; - struct grid_floor_item { - int index; - String element; - int rotation; - }; - struct grid_floor_item_node { - Spatial *node; - }; - -protected: - ElementData() - { - ecs.component(); - ecs.component(); - ecs.component(); - ecs.component(); - ecs.component(); - ecs.component(); - ecs.component(); - flecs::entity e = ecs.entity("grid_layouts"); - e.add(); - create_new_layout("default"); - create_new_exterior_floor("default"); - create_new_interior_floor("default"); - load_data(); - struct grid_element_type t_empty; - struct grid_element e_empty; - t_empty.name = "empty"; - e_empty.name = "empty"; - e_empty.type = "empty"; - element_type["empty"] = t_empty; - elements["empty"] = e_empty; - ecs.observer() - .event(flecs::OnRemove) - .each([](flecs::entity em, - struct grid_floor_item_node &s) { - if (s.node) - s.node->queue_delete(); - s.node = nullptr; - }); - } - HashMap element_type; - HashMap elements; - -public: - void create_new_layout(const String &key) - { - flecs::entity top = ecs.lookup("grid_layouts"); - assert(top.is_valid()); - flecs::entity layout = - ecs.entity(key.ascii().ptr()).child_of(top); - // one floor by default - layout.add(); - flecs::entity extr = ecs.entity("exterior").child_of(layout); - extr.add(); - flecs::entity intr = ecs.entity("interior").child_of(layout); - intr.add(); - intr.set({ 0 }); - extr.set({ 0 }); - } - void create_new_exterior_floor(const String &key) - { - int i; - flecs::entity ext = get_base(key, true); - assert(ext.is_valid()); - struct grid_layout_base *l = ext.get_mut(); - int floor = l->floor_count; - flecs::entity fl = - ecs.entity(("floor_" + itos(floor)).ascii().ptr()) - .child_of(ext); - assert(fl.is_valid()); - - for (i = 0; i < grid_size * grid_size; i++) { - flecs::entity item = - ecs.entity(("item_" + itos(i)).ascii().ptr()) - .child_of(fl); - item.set({ i, "empty", 0 }); - } - l->floor_count++; - } - void create_new_interior_floor(const String &key) - { - int i; - flecs::entity intr = get_base(key, false); - assert(intr.is_valid()); - struct grid_layout_base *l = intr.get_mut(); - int floor = l->floor_count; - flecs::entity fl = - ecs.entity(("floor_" + itos(floor)).ascii().ptr()) - .child_of(intr); - assert(fl.is_valid()); - - for (i = 0; i < grid_size * grid_size; i++) { - flecs::entity item = - ecs.entity(("item_" + itos(i)).ascii().ptr()) - .child_of(fl); - item.set({ i, "empty", 0 }); - } - l->floor_count++; - } - inline int constexpr get_grid_size() - { - return grid_size; - } - flecs::entity get_base(const String &key, bool exterior) const - { - flecs::entity top = ecs.lookup("grid_layouts"); - assert(top.is_valid()); - flecs::entity layout = top.lookup(key.ascii().ptr()); - assert(layout.is_valid()); - flecs::entity base; - if (exterior) - base = layout.lookup("exterior"); - else - base = layout.lookup("interior"); - return base; - } - flecs::entity get_floor(const String &key, bool exterior, int fl) const - { - flecs::entity base = get_base(key, exterior); - assert(base.is_valid()); - String floor_key = "floor_" + itos(fl); - flecs::entity floor_e = base.lookup(floor_key.ascii().ptr()); - return floor_e; - } - bool has_floor(const String &key, bool exterior, int fl) const - { - flecs::entity floor_e = get_floor(key, exterior, fl); - if (!floor_e.is_valid()) - return false; - flecs::entity item_e = floor_e.lookup("item_0"); - return item_e.is_valid(); - } - void ensure_floor(const String &key, bool exterior, int fl) - { - int i; - if (has_floor(key, exterior, fl)) - return; - flecs::entity base = get_base(key, exterior); - flecs::entity floor_e = - ecs.entity(("floor_" + itos(fl)).ascii().ptr()) - .child_of(base); - assert(floor_e.is_valid()); - for (i = 0; i < grid_size * grid_size; i++) { - flecs::entity item = - ecs.entity(("item_" + itos(i)).ascii().ptr()) - .child_of(floor_e); - item.set({ i, "empty", 0 }); - } - assert(has_floor(key, exterior, fl)); - print_line("ensured floor: " + itos(fl)); - } - inline flecs::entity get_grid_entity(const String &key, bool exterior, - int fl, int i) const - { - flecs::entity base = get_floor(key, exterior, fl); - assert(base.is_valid()); - String item_key = "item_" + itos(i); - flecs::entity item_data = base.lookup(item_key.ascii().ptr()); - if (!item_data.is_valid()) - print_error("lookup failed: " + item_key); - assert(item_data.is_valid()); - return item_data; - } - inline const String &get_grid_element(const String &key, bool exterior, - int fl, int i) const - { - flecs::entity item_data = get_grid_entity(key, exterior, fl, i); - const String &element = - item_data.get()->element; - return element; - } - inline int get_grid_rotation(const String &key, bool exterior, int fl, - int i) const - { - flecs::entity item_data = get_grid_entity(key, exterior, fl, i); - int rotation = item_data.get()->rotation; - return rotation; - } - void set_grid_element(const String &key, bool exterior, int fl, int i, - const String &element) - { - flecs::entity item_data = get_grid_entity(key, exterior, fl, i); - item_data.get_mut()->element = element; - } - void set_grid_rotation(const String &key, bool exterior, int fl, int i, - int rotation) - { - flecs::entity item_data = get_grid_entity(key, exterior, fl, i); - item_data.get_mut()->rotation = rotation; - } - Spatial *get_grid_node(const String &key, bool exterior, int fl, int i) - { - assert(has_floor(key, exterior, fl)); - flecs::entity item_data = get_grid_entity(key, exterior, fl, i); - if (!item_data.has()) { - Spatial *sp = memnew(Spatial); - get_as_node("%bg_floor") - ->call_deferred("add_child", sp); - item_data.set({ sp }); - int x = i % grid_size; - int z = i / grid_size; - int rotation = get_grid_rotation(key, exterior, fl, i); - sp->set_transform(Transform( - Basis().rotated(Vector3(0, 1, 0), - Math_PI * rotation / 2.0f), - Vector3((x - 4) * 4, 1 + 5 * fl, (z - 4) * 4) - - get_as_node("%bg_floor") - ->get_transform() - .origin)); - } - return item_data.get()->node; - } - int get_closest_node_on_floor(const String &key, bool exterior, int fl, - const Vector3 &position) - { - int i; - assert(has_floor(key, exterior, fl)); - flecs::entity floor_e = get_floor(key, exterior, fl); - assert(floor_e.is_valid()); - int selected = -1; - float dst = Math_INF; - for (i = 0; i < grid_size * grid_size; i++) { - Spatial *node = get_grid_node(key, exterior, fl, i); - Vector3 pos = node->get_transform().origin; - float mdst = position.distance_squared_to(pos); - if (dst > mdst) { - dst = mdst; - selected = i; - } - } - return selected; - } - void get_grid_layouts_key_list(List *keys) - { - flecs::entity top = ecs.lookup("grid_layouts"); - assert(top.is_valid()); - flecs::query_builder qb = - ecs.query_builder().with( - flecs::ChildOf, top); - flecs::query q = qb.build(); - q.each([keys](flecs::entity e, const struct grid_layout &data) { - keys->push_back(String(e.name())); - }); - } - void serialize_layouts(Dictionary &store) - { - flecs::entity top = ecs.lookup("grid_layouts"); - assert(top.is_valid()); - top.children([this, &store](flecs::entity l) { - Dictionary layout, exterior_layout, interior_layout; - if (l.has()) { - flecs::entity intr = l.lookup("interior"); - assert(intr.is_valid()); - flecs::entity extr = l.lookup("exterior"); - assert(extr.is_valid()); - intr.children([this, &interior_layout]( - flecs::entity intr_fl) { - if (intr_fl.has()) { - Array items; - intr_fl.children([&items]( - flecs::entity - floor_item) { - if (floor_item.has< - struct grid_floor_item>()) { - const struct grid_floor_item *item = - floor_item - .get(); - Dictionary sitem; - sitem["index"] = - item->index; - sitem["element"] = - item->element; - sitem["rotation"] = - item->rotation; - items.push_back( - sitem); - } - }); - String floor_key( - intr_fl.name()); - interior_layout[floor_key] = - items; - } - }); - extr.children([this, &exterior_layout]( - flecs::entity extr_fl) { - Array items; - extr_fl.children([&items]( - flecs::entity - floor_item) { - if (floor_item.has< - struct grid_floor_item>()) { - const struct grid_floor_item *item = - floor_item.get< - struct grid_floor_item>(); - Dictionary sitem; - sitem["index"] = - item->index; - sitem["element"] = - item->element; - sitem["rotation"] = - item->rotation; - items.push_back(sitem); - } - }); - String floor_key(extr_fl.name()); - exterior_layout[floor_key] = items; - }); - layout["interior"] = interior_layout; - layout["exterior"] = exterior_layout; - } - String layout_name(l.name()); - store[layout_name] = layout; - }); - } - void unserialize_layouts(const Dictionary &store) - { - int i; - flecs::entity top = ecs.lookup("grid_layouts"); - assert(top.is_valid()); - // delete all layouts - top.children([this](flecs::entity l) { l.destruct(); }); - List layout_keys; - store.get_key_list(&layout_keys); - List::Element *e; - e = layout_keys.front(); - while (e) { - String layout_name = e->get(); - flecs::entity layout = - ecs.entity(layout_name.ascii().ptr()) - .child_of(top); - layout.add(); - flecs::entity extr = - ecs.entity("exterior").child_of(layout); - extr.add(); - extr.set({ 0 }); - flecs::entity intr = - ecs.entity("interior").child_of(layout); - intr.add(); - intr.set({ 0 }); - Dictionary store_layout = store[e->get()]; - Dictionary store_interior = store_layout["interior"]; - Dictionary store_exterior = store_layout["exterior"]; - List::Element *ve; - List interior_keys; - List exterior_keys; - store_interior.get_key_list(&interior_keys); - store_exterior.get_key_list(&exterior_keys); - for (ve = interior_keys.front(); ve; ve = ve->next()) { - String floor_key = ve->get(); - if (floor_key.begins_with("floor_")) { - flecs::entity floor_e = - ecs.entity(floor_key.ascii() - .ptr()) - .child_of(intr); - assert(floor_e.is_valid()); - floor_e.add(); - const Array &floor_interior = - store_interior[floor_key]; - for (i = 0; i < floor_interior.size(); - i++) { - const Dictionary &item = - floor_interior[i]; - int index = item["index"]; - String element = - item["element"]; - int rotation = item["rotation"]; - String item_key = - "item_" + itos(index); - flecs::entity item_e = - ecs.entity(item_key.ascii() - .ptr()) - .child_of( - floor_e); - item_e.set( - { index, element, - rotation }); - } - struct grid_layout_base *l = intr.get_mut< - struct grid_layout_base>(); - l->floor_count++; - } - } - for (ve = exterior_keys.front(); ve; ve = ve->next()) { - String floor_key = ve->get(); - if (floor_key.begins_with("floor_")) { - flecs::entity floor_e = - ecs.entity(floor_key.ascii() - .ptr()) - .child_of(extr); - assert(floor_e.is_valid()); - floor_e.add(); - const Array &floor_exterior = - store_exterior[floor_key]; - for (i = 0; i < floor_exterior.size(); - i++) { - const Dictionary &item = - floor_exterior[i]; - int index = item["index"]; - String element = - item["element"]; - int rotation = item["rotation"]; - String item_key = - "item_" + itos(index); - flecs::entity item_e = - ecs.entity(item_key.ascii() - .ptr()) - .child_of( - floor_e); - item_e.set( - { index, element, - rotation }); - } - struct grid_layout_base *l = extr.get_mut< - struct grid_layout_base>(); - l->floor_count++; - } - } - e = e->next(); - } - } - void get_element_type_key_list(List *keys) - { - element_type.get_key_list(keys); - } - void create_element_type(const String &key) - { - assert(!element_type.has(key)); - struct grid_element_type g; - g.name = key; - element_type[key] = g; - } - void set_element_type_socket(const String &key, int socket, - const Transform &xform) - { - assert(element_type.has(key)); - assert(socket >= 0 && socket < ELEMENT_SOCKETS); - element_type[key].sockets[socket] = xform; - } - void set_element_type_name(const String &key, const String &name) - { - assert(element_type.has(key)); - element_type[key].name = name; - } - bool has_element_type(const String &key) - { - return element_type.has(key); - } - Transform get_element_type_socket(const String &key, int socket) - { - assert(element_type.has(key)); - assert(socket >= 0 && socket < ELEMENT_SOCKETS); - return element_type[key].sockets[socket]; - } - int get_element_type_size() - { - return element_type.size(); - } - void create_element(const String &key, const String &type) - { - struct grid_element g; - assert(!elements.has(key)); - assert(element_type.has(type)); - g.name = key; - g.type = type; - elements[key] = g; - } - void set_element_type(const String &key, const String &type) - { - assert(elements.has(key)); - assert(element_type.has(type)); - elements[key].type = type; - } - const String &get_element_type(const String &key) const - { - assert(elements.has(key)); - return elements[key].type; - } - void set_element_mesh_name(const String &key, int socket, - const String &mesh_name) - { - assert(elements.has(key)); - assert(socket >= 0 && socket < ELEMENT_SOCKETS); - elements[key].mesh_names[socket] = mesh_name; - } - const String &get_element_mesh_name(const String &key, int socket) - { - assert(elements.has(key)); - assert(socket >= 0 && socket < ELEMENT_SOCKETS); - return elements[key].mesh_names[socket]; - } - int get_element_size() - { - return elements.size(); - } - void get_element_key_list(List *keys) - { - elements.get_key_list(keys); - } - bool has_element(const String &key) - { - return elements.has(key); - } - void save_data() - { - int i; - ConfigFile config; - Dictionary conf_element_types; - Dictionary conf_elements; - Dictionary conf_exterior_grid; - List keys; - List::Element *e; - element_type.get_key_list(&keys); - e = keys.front(); - while (e) { - Dictionary item; - const struct grid_element_type &g = - element_type[e->get()]; - if (e->get() == "empty") { - e = e->next(); - continue; - } - item["name"] = e->get(); - Array sockets; - sockets.resize(ELEMENT_SOCKETS); - for (i = 0; i < ELEMENT_SOCKETS; i++) - sockets[i] = g.sockets[i]; - item["sockets"] = sockets; - - conf_element_types[e->get()] = item; - e = e->next(); - } - keys.clear(); - elements.get_key_list(&keys); - e = keys.front(); - while (e) { - Dictionary item; - const struct grid_element &g = elements[e->get()]; - if (e->get() == "empty") { - e = e->next(); - continue; - } - item["name"] = e->get(); - item["type"] = g.type; - Array mesh_names; - mesh_names.resize(ELEMENT_SOCKETS); - for (i = 0; i < ELEMENT_SOCKETS; i++) - mesh_names[i] = g.mesh_names[i]; - item["mesh_names"] = mesh_names; - - conf_elements[e->get()] = item; - e = e->next(); - } - // TODO: support multiple layouts; - serialize_layouts(conf_exterior_grid); - - config.set_value("buildings_layout", "element_types", - conf_element_types); - config.set_value("buildings_layout", "elements", conf_elements); - config.set_value("buildings_layout", "grid_layouts", - conf_exterior_grid); - config.save("res://astream/blayout.conf"); - } - void load_data() - { - int i; - ConfigFile config; - Dictionary conf_element_types; - Dictionary conf_elements; - Dictionary conf_grid_layouts; - List keys; - List::Element *e; - elements.clear(); - element_type.clear(); - config.load("res://astream/blayout.conf"); - conf_element_types = config.get_value( - "buildings_layout", "element_types", Dictionary()); - conf_elements = config.get_value("buildings_layout", "elements", - Dictionary()); - conf_grid_layouts = config.get_value( - "buildings_layout", "grid_layouts", Dictionary()); - conf_element_types.get_key_list(&keys); - e = keys.front(); - while (e) { - String key = e->get(); - Dictionary item = conf_element_types[key]; - assert(item.has("sockets")); - create_element_type(key); - Array sockets = item["sockets"]; - for (i = 0; i < sockets.size(); i++) - set_element_type_socket(key, i, sockets[i]); - e = e->next(); - } - keys.clear(); - conf_elements.get_key_list(&keys); - e = keys.front(); - while (e) { - String key = e->get(); - Dictionary item = conf_elements[key]; - assert(item.has("type")); - assert(item.has("mesh_names")); - String type = item["type"]; - print_line("loading element: " + key + - " type: " + type); - if (key == "empty") { - e = e->next(); - continue; - } - create_element(key, type); - Array mesh_names = item["mesh_names"]; - for (i = 0; i < mesh_names.size(); i++) - set_element_mesh_name(key, i, mesh_names[i]); - e = e->next(); - } - unserialize_layouts(conf_grid_layouts); - } -}; -ElementData *ElementData::singleton = nullptr; - class LayoutEditor : public Object { GDCLASS(LayoutEditor, Object) BuildingLayoutEditor *editor; @@ -737,6 +28,7 @@ class LayoutEditor : public Object { String current_layout; bool is_exterior; int current_floor; + String select_rotation; public: LayoutEditor(BuildingLayoutEditor *editor) @@ -748,6 +40,7 @@ public: , current_layout("default") , is_exterior(true) , current_floor(0) + , select_rotation("%select_rotation") { get_as_node(grid_elements) ->connect("item_selected", this, "select_grid_element"); @@ -755,6 +48,11 @@ public: sb->connect("value_changed", this, "set_current_floor"); sb->set_min(-6); sb->set_max(6); + get_as_node(select_rotation) + ->connect("item_selected", this, + "select_grid_rotation"); + get_as_node