ECS redesign for buildings layout editor

This commit is contained in:
2024-10-07 18:38:46 +03:00
parent 64a66d1c50
commit f62dbbf505
2 changed files with 581 additions and 95 deletions

View File

@@ -64,249 +64,336 @@ elements={
"type": "e1"
}
}
exterior_grid={
"default": [ {
grid_layouts={
"default": {
"exterior": {
"floor_0": [ {
"element": "empty",
"index": 0,
"rotation": 0
}, {
"element": "empty",
"index": 1,
"rotation": 0
}, {
"element": "empty",
"index": 2,
"rotation": 0
}, {
"element": "empty",
"index": 3,
"rotation": 0
}, {
"element": "empty",
"index": 4,
"rotation": 0
}, {
"element": "empty",
"index": 5,
"rotation": 0
}, {
"element": "empty",
"index": 6,
"rotation": 0
}, {
"element": "empty",
"index": 7,
"rotation": 0
}, {
"element": "empty",
"index": 8,
"rotation": 0
}, {
"element": "empty",
"index": 9,
"rotation": 0
}, {
"element": "empty",
"index": 10,
"rotation": 0
}, {
"element": "empty",
"index": 11,
"rotation": 0
}, {
"element": "empty",
"index": 12,
"rotation": 0
}, {
"element": "empty",
"index": 13,
"rotation": 0
}, {
"element": "empty",
"index": 14,
"rotation": 0
}, {
"element": "empty",
"index": 15,
"rotation": 0
}, {
"element": "empty",
"index": 16,
"rotation": 0
}, {
"element": "empty",
"index": 17,
"rotation": 0
}, {
"element": "empty",
"index": 18,
"rotation": 0
}, {
"element": "empty",
"index": 19,
"rotation": 0
}, {
"element": "empty",
"index": 20,
"rotation": 0
}, {
"element": "empty",
"index": 21,
"rotation": 0
}, {
"element": "empty",
"index": 22,
"rotation": 0
}, {
"element": "empty",
"index": 23,
"rotation": 0
}, {
"element": "empty",
"index": 24,
"rotation": 0
}, {
"element": "empty",
"index": 25,
"rotation": 0
}, {
"element": "empty",
"index": 26,
"rotation": 0
}, {
"element": "empty",
"index": 27,
"rotation": 0
}, {
"element": "empty",
"index": 28,
"rotation": 0
}, {
"element": "empty",
"index": 29,
"rotation": 0
}, {
"element": "empty",
"index": 30,
"rotation": 0
}, {
"element": "empty",
"index": 31,
"rotation": 0
}, {
"element": "empty",
"index": 32,
"rotation": 0
}, {
"element": "empty",
"index": 33,
"rotation": 0
}, {
"element": "empty",
"index": 34,
"rotation": 0
}, {
"element": "empty",
"index": 35,
"rotation": 0
}, {
"element": "empty",
"index": 36,
"rotation": 0
}, {
"element": "empty",
"index": 37,
"rotation": 0
}, {
"element": "empty",
"index": 38,
"rotation": 0
}, {
"element": "empty",
"index": 39,
"rotation": 0
}, {
"element": "empty",
"index": 40,
"rotation": 0
}, {
"element": "empty",
"index": 41,
"rotation": 0
}, {
"element": "empty",
"index": 42,
"rotation": 0
}, {
"element": "empty",
"index": 43,
"rotation": 0
}, {
"element": "empty",
"index": 44,
"rotation": 0
}, {
"element": "empty",
"index": 45,
"rotation": 0
}, {
"element": "empty",
"index": 46,
"rotation": 0
}, {
"element": "empty",
"index": 47,
"rotation": 0
}, {
"element": "empty",
"index": 48,
"rotation": 0
}, {
"element": "empty",
"index": 49,
"rotation": 0
}, {
"element": "empty",
"index": 50,
"rotation": 0
}, {
"element": "empty",
"index": 51,
"rotation": 0
}, {
"element": "empty",
"index": 52,
"rotation": 0
}, {
"element": "empty",
"index": 53,
"rotation": 0
}, {
"element": "empty",
"index": 54,
"rotation": 0
}, {
"element": "empty",
"index": 55,
"rotation": 0
}, {
"element": "empty",
"index": 56,
"rotation": 0
}, {
"element": "empty",
"index": 57,
"rotation": 0
}, {
"element": "empty",
"index": 58,
"rotation": 0
}, {
"element": "empty",
"index": 59,
"rotation": 0
}, {
"element": "empty",
"index": 60,
"rotation": 0
}, {
"element": "empty",
"index": 61,
"rotation": 0
}, {
"element": "empty",
"index": 62,
"rotation": 0
}, {
"element": "empty",
"index": 63,
"rotation": 0
}, {
"element": "empty",
"index": 64,
"rotation": 0
}, {
"element": "empty",
"index": 65,
"rotation": 0
}, {
"element": "empty",
"index": 66,
"rotation": 0
}, {
"element": "empty",
"index": 67,
"rotation": 0
}, {
"element": "empty",
"index": 68,
"rotation": 0
}, {
"element": "empty",
"index": 69,
"rotation": 0
}, {
"element": "empty",
"index": 70,
"rotation": 0
}, {
"element": "empty",
"index": 71,
"rotation": 0
}, {
"element": "empty",
"element": "corner",
"index": 72,
"rotation": 0
}, {
"element": "empty",
"element": "side_window",
"index": 73,
"rotation": 0
}, {
"element": "empty",
"element": "side_window",
"index": 74,
"rotation": 0
}, {
"element": "empty",
"element": "side_door",
"index": 75,
"rotation": 0
}, {
"element": "empty",
"element": "side_window",
"index": 76,
"rotation": 0
}, {
"element": "empty",
"element": "side_window",
"index": 77,
"rotation": 0
}, {
"element": "empty",
"element": "side_wall",
"index": 78,
"rotation": 0
}, {
"element": "empty",
"index": 79,
"rotation": 0
}, {
"element": "empty",
"index": 80,
"rotation": 0
} ]
},
"interior": {
}
}
}

View File

@@ -14,6 +14,7 @@
#include <scene/gui/button.h>
#include <scene/gui/menu_button.h>
#include <editor/editor_node.h>
#include <flecs/flecs.h>
#include "editor_event.h"
#include "building_layout_editor.h"
@@ -36,10 +37,43 @@ template <class T> T *get_as_node(const String &path)
return ret;
}
template <class T>
void select_control_item(const String &path, const String &item)
{
int i;
T *ctl = get_as_node<T>(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 <class T> 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 {
public:
flecs::world ecs;
static ElementData *singleton;
public:
static ElementData *get_singleton()
{
if (!singleton)
@@ -66,13 +100,37 @@ public:
String element;
int rotation;
};
Vector<struct grid_cell> grid;
struct grid_layouts {};
struct grid_layout {
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()
{
grid.resize(grid_size * grid_size);
grid.fill({ "empty", 0 });
ecs.component<struct grid_layouts>();
ecs.component<struct grid_layout>();
ecs.component<struct grid_layout_exterior>();
ecs.component<struct grid_layout_interior>();
ecs.component<struct grid_floor>();
ecs.component<struct grid_floor_item>();
ecs.component<struct grid_floor_item_node>();
flecs::entity e = ecs.entity("grid_layouts");
e.add<grid_layouts>();
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;
@@ -81,34 +139,370 @@ protected:
e_empty.type = "empty";
element_type["empty"] = t_empty;
elements["empty"] = e_empty;
ecs.observer<struct grid_floor_item_node>()
.event(flecs::OnRemove)
.each([](flecs::entity em,
struct grid_floor_item_node &s) {
if (s.node)
s.node->queue_delete();
s.node = nullptr;
});
}
HashMap<String, struct grid_element_type> element_type;
HashMap<String, struct grid_element> 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.set<grid_layout>({ 0 });
flecs::entity extr = ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>();
flecs::entity intr = ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>();
}
void create_new_exterior_floor(const String &key)
{
int i;
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor = l->floor_count;
flecs::entity ext = layout.lookup("exterior");
assert(ext.is_valid());
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<grid_floor_item>({ i, "empty", 0 });
}
l->floor_count++;
}
void create_new_interior_floor(const String &key)
{
int i;
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor = l->floor_count;
flecs::entity intr = layout.lookup("interior");
assert(intr.is_valid());
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<grid_floor_item>({ i, "empty", 0 });
}
l->floor_count++;
}
inline int constexpr get_grid_size()
{
return grid_size;
}
inline const String &get_grid_element(int i) const
inline flecs::entity get_grid_entity(const String &key, bool exterior,
int fl, int i) const
{
assert(i >= 0 && i < grid_size * grid_size);
return grid[i].element;
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor_count = l->floor_count;
assert(fl >= 0 && fl < floor_count);
flecs::entity base;
if (exterior)
base = layout.lookup("exterior");
else
base = layout.lookup("interior");
assert(base.is_valid());
String floor_key = "floor_" + itos(fl);
String item_key = "item_" + itos(i);
flecs::entity item_data = base.lookup(
(floor_key + "::" + item_key).ascii().ptr());
if (!item_data.is_valid())
print_error("lookup failed: " + floor_key +
"::" + item_key);
assert(item_data.is_valid());
return item_data;
}
inline int get_grid_rotation(int i) const
inline const String &get_grid_element(const String &key, bool exterior,
int fl, int i) const
{
assert(i >= 0 && i < grid_size * grid_size);
return grid[i].rotation;
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
const String &element =
item_data.get<grid_floor_item>()->element;
return element;
}
void set_grid_element(int i, const String &element)
inline int get_grid_rotation(const String &key, bool exterior, int fl,
int i) const
{
assert(i >= 0 && i < grid_size * grid_size);
grid.write[i].element = element;
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
int rotation = item_data.get<grid_floor_item>()->rotation;
return rotation;
}
void set_grid_rotation(int i, int rotation)
void set_grid_element(const String &key, bool exterior, int fl, int i,
const String &element)
{
assert(i >= 0 && i < grid_size * grid_size);
grid.write[i].rotation = rotation;
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
item_data.get_mut<grid_floor_item>()->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<grid_floor_item>()->rotation = rotation;
}
Spatial *get_grid_node(const String &key, bool exterior, int fl, int i)
{
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
if (!item_data.has<struct grid_floor_item_node>()) {
Spatial *sp = memnew(Spatial);
get_as_node<Spatial>("%bg_floor")
->call_deferred("add_child", sp);
item_data.set<struct grid_floor_item_node>({ 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, 0, (z - 4) * 4) -
get_as_node<Spatial>("%bg_floor")
->get_transform()
.origin));
}
return item_data.get<struct grid_floor_item_node>()->node;
}
int get_closest_node_on_floor(const String &key, bool exterior, int fl,
const Vector3 &position)
{
int i;
String full_key = "grid_layouts::" + key;
if (exterior)
full_key += "::exterior";
else
full_key += "::interior";
String floor_key = "floor_" + itos(fl);
full_key += "::" + floor_key;
flecs::entity floor_e = ecs.lookup(full_key.ascii().ptr());
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<String> *keys)
{
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::query_builder<const struct grid_layout> qb =
ecs.query_builder<const struct grid_layout>().with(
flecs::ChildOf, top);
flecs::query<const struct grid_layout> 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<struct grid_layout>()) {
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<struct grid_floor>()) {
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<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(
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<Variant> layout_keys;
store.get_key_list(&layout_keys);
List<Variant>::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.set<grid_layout>({ 0 });
flecs::entity extr =
ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>();
flecs::entity intr =
ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>();
Dictionary store_layout = store[e->get()];
Dictionary store_interior = store_layout["interior"];
Dictionary store_exterior = store_layout["exterior"];
List<Variant>::Element *ve;
List<Variant> interior_keys;
List<Variant> 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<struct grid_floor>();
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<grid_floor_item>(
{ index, element,
rotation });
}
struct grid_layout *l = layout.get_mut<
struct grid_layout>();
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<struct grid_floor>();
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<grid_floor_item>(
{ index, element,
rotation });
}
struct grid_layout *l = layout.get_mut<
struct grid_layout>();
l->floor_count++;
}
}
e = e->next();
}
}
void get_element_type_key_list(List<String> *keys)
{
@@ -243,20 +637,12 @@ public:
e = e->next();
}
// TODO: support multiple layouts;
Array default_grid;
default_grid.resize(grid_size * grid_size);
for (i = 0; i < grid_size * grid_size; i++) {
Dictionary item;
item["element"] = grid[i].element;
item["rotation"] = grid[i].rotation;
default_grid[i] = item;
}
conf_exterior_grid["default"] = default_grid;
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", "exterior_grid",
config.set_value("buildings_layout", "grid_layouts",
conf_exterior_grid);
config.save("res://astream/blayout.conf");
}
@@ -266,7 +652,7 @@ public:
ConfigFile config;
Dictionary conf_element_types;
Dictionary conf_elements;
Dictionary conf_exterior_grid;
Dictionary conf_grid_layouts;
List<Variant> keys;
List<Variant>::Element *e;
elements.clear();
@@ -276,8 +662,8 @@ public:
"buildings_layout", "element_types", Dictionary());
conf_elements = config.get_value("buildings_layout", "elements",
Dictionary());
conf_exterior_grid = config.get_value(
"buildings_layout", "exterior_grid", Dictionary());
conf_grid_layouts = config.get_value(
"buildings_layout", "grid_layouts", Dictionary());
conf_element_types.get_key_list(&keys);
e = keys.front();
while (e) {
@@ -311,6 +697,8 @@ public:
set_element_mesh_name(key, i, mesh_names[i]);
e = e->next();
}
unserialize_layouts(conf_grid_layouts);
#if 0
if (conf_exterior_grid.has("default")) {
Array default_grid = conf_exterior_grid["default"];
if (default_grid.size() == grid_size * grid_size) {
@@ -323,6 +711,7 @@ public:
}
}
}
#endif
}
};
ElementData *ElementData::singleton = nullptr;
@@ -331,7 +720,6 @@ class LayoutEditor : public Object {
GDCLASS(LayoutEditor, Object)
BuildingLayoutEditor *editor;
String grid_elements;
Vector<Spatial *> grid_nodes;
int current_cell;
public:
@@ -364,37 +752,30 @@ public:
int grid_size =
ElementData::get_singleton()->get_grid_size();
assert(grid_size > 0);
grid_nodes.resize(grid_size * grid_size);
const String layout_key = "default";
bool exterior = true;
int floor = 0;
for (i = 0; i < grid_size * grid_size; i++) {
int x = i % grid_size;
int z = i / grid_size;
Spatial *node = memnew(Spatial);
int rotation = ElementData::get_singleton()
->get_grid_rotation(i);
get_as_node<Spatial>("%bg_floor")
->call_deferred("add_child", node);
node->set_transform(Transform(
Basis().rotated(Vector3(0, 1, 0),
Math_PI * rotation /
2.0f),
Vector3((x - 4) * 4, 0, (z - 4) * 4) -
get_as_node<Spatial>("%bg_floor")
->get_transform()
.origin));
String element = ElementData::get_singleton()
->get_grid_element(i);
Spatial *node =
ElementData::get_singleton()
->get_grid_node(layout_key,
exterior, floor,
i);
String element =
ElementData::get_singleton()
->get_grid_element(layout_key,
exterior,
floor, i);
editor->visualize_element_at(element, node);
grid_nodes.write[i] = node;
print_line("element: " + element);
}
assert(grid_nodes.size() > 0);
}
editor->get_viewport()->get_camera()->set_global_translation(
Vector3(-14, 23, 32));
List<String> element_keys;
List<String>::Element *e;
ElementData::get_singleton()->get_element_type_key_list(
ElementData::get_singleton()->get_element_key_list(
&element_keys);
e = element_keys.front();
get_as_node<OptionButton>(grid_elements)->clear();
@@ -415,7 +796,6 @@ public:
}
void event_signal_handler(const String &event, const Array &args)
{
int i;
print_line("event: " + event);
if (event == "mouse_press") {
Vector2 position = args[0];
@@ -441,40 +821,71 @@ public:
Math::stepify(proj.z, 4.0f)));
get_as_node<Spatial>("%refcube")
->set_global_transform(xf);
float dst = Math_INF;
int selected = -1;
for (i = 0; i < grid_nodes.size(); i++) {
assert(grid_nodes[i]->is_inside_tree());
Vector3 o =
grid_nodes[i]
->get_global_transform()
.origin;
float mdst = o.distance_squared_to(
xf.origin);
if (dst > mdst) {
selected = i;
dst = mdst;
}
}
String layout_key = "default";
bool exterior = true;
int floor = 0;
int selected =
ElementData::get_singleton()
->get_closest_node_on_floor(
layout_key, exterior,
floor, xf.origin);
if (selected >= 0) {
current_cell = selected;
get_as_node<Spatial>("%refcube")
->set_global_transform(
grid_nodes[current_cell]
ElementData::get_singleton()
->get_grid_node(
layout_key,
exterior,
floor,
current_cell)
->get_global_transform());
print_line(
"cell: " + itos(current_cell) +
"pos: " +
(grid_nodes[current_cell]
(ElementData::get_singleton()
->get_grid_node(
layout_key,
exterior,
floor,
current_cell)
->get_global_transform()
.origin
.operator String()));
String element =
ElementData::get_singleton()
->get_grid_element(
layout_key,
exterior, floor,
current_cell);
select_control_item<OptionButton>(
"%grid_elements", element);
}
}
}
}
void select_grid_element(int index)
{
String layout_key = "default";
bool exterior = true;
int floor = 0;
print_line("selected: " + itos(current_cell) + " " +
itos(index));
const String &element =
get_as_node<OptionButton>("%grid_elements")
->get_item_text(index);
ElementData::get_singleton()->set_grid_element(
layout_key, exterior, floor, current_cell, element);
editor->visualize_element_at(
element,
ElementData::get_singleton()->get_grid_node(
layout_key, exterior, floor, current_cell));
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("select_grid_element", "index"),
&LayoutEditor::select_grid_element);
}
};
@@ -588,7 +999,7 @@ public:
}
void select_element(int element)
{
int i, j;
int i;
print_line("selected element: " + itos(element));
String item = get_as_node<ItemList>("%element_list")
->get_item_text(element);
@@ -614,27 +1025,13 @@ public:
ElementData::get_singleton()->set_element_type(
current_element, b->get_item_text(0));
}
int selected = 0;
for (i = 0; i < used_socket_count; i++) {
String selected_mesh =
ElementData::get_singleton()
->get_element_mesh_name(current_element,
i);
selected = 0;
for (j = 0;
j < mesh_select_buttons[i]->get_item_count();
j++) {
String mesh_item =
mesh_select_buttons[i]->get_item_text(
j);
if (mesh_item == selected_mesh) {
selected = j;
break;
}
}
print_line(itos(i) +
": selecting mesh: " + itos(selected));
mesh_select_buttons[i]->select(selected);
select_control_item<OptionButton>(
mesh_select_buttons[i], selected_mesh);
}
editor->visualize_element_type(type, current_element);
}
@@ -1186,6 +1583,8 @@ void BuildingLayoutEditor::visualize_element_at(const String &element,
return;
const String &element_type =
ElementData::get_singleton()->get_element_type(element);
for (i = 0; i < node->get_child_count(); i++)
node->get_child(i)->queue_delete();
for (i = 0; i < ELEMENT_SOCKETS; i++) {
Transform xform =
ElementData::get_singleton()->get_element_type_socket(