Worked on building layout editor

This commit is contained in:
2024-10-06 09:08:28 +03:00
parent 6986a4a334
commit 0e5a2e7f9b
7 changed files with 960 additions and 207 deletions

312
godot/astream/blayout.conf Normal file
View File

@@ -0,0 +1,312 @@
[buildings_layout]
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 ) ]
},
"e1": {
"name": "e1",
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 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 ) ]
},
"e2": {
"name": "e2",
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 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 ) ]
},
"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 ) ]
},
"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 ) ]
}
}
elements={
"corner": {
"mesh_names": [ "exterior_floor3", "exterior_wall2", "", "", "exterior_wall2", "exterior_corner2", "", "", "", "", "", "", "", "", "", "" ],
"name": "corner",
"type": "corner1"
},
"f1": {
"mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "f1",
"type": "e1"
},
"f2": {
"mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "f2",
"type": "e1"
},
"normal_floor": {
"mesh_names": [ "exterior_floor", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "normal_floor",
"type": "just_floor"
},
"side_door": {
"mesh_names": [ "exterior_floor2", "", "", "", "exterior_door1", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "side_door",
"type": "side_wall"
},
"side_wall": {
"mesh_names": [ "exterior_floor2", "", "", "", "exterior_wall1", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "side_wall",
"type": "side_wall"
},
"side_window": {
"mesh_names": [ "exterior_floor2", "", "", "", "exterior_window1", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "side_window",
"type": "side_wall"
},
"test_element": {
"mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "test_element",
"type": "e1"
}
}
exterior_grid={
"default": [ {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
}, {
"element": "empty",
"rotation": 0
} ]
}

View File

@@ -1,11 +1,25 @@
[gd_scene load_steps=4 format=2] [gd_scene load_steps=7 format=2]
[ext_resource path="res://main/building_layout_editor.gd" type="Script" id=1] [ext_resource path="res://main/building_layout_editor.gd" type="Script" id=1]
[ext_resource path="res://astream/building-layouts/building-elements.glb" type="PackedScene" id=2] [ext_resource path="res://astream/building-layouts/building-elements.glb" type="PackedScene" id=2]
[sub_resource type="SpatialMaterial" id=4]
flags_transparent = true
albedo_color = Color( 1, 1, 1, 0.654902 )
[sub_resource type="CubeMesh" id=1] [sub_resource type="CubeMesh" id=1]
material = SubResource( 4 )
size = Vector3( 40, 1, 40 ) size = Vector3( 40, 1, 40 )
[sub_resource type="SpatialMaterial" id=2]
flags_transparent = true
flags_unshaded = true
albedo_color = Color( 0.745098, 0.105882, 0.105882, 0.192157 )
[sub_resource type="CubeMesh" id=3]
material = SubResource( 2 )
size = Vector3( 4, 8, 4 )
[node name="building_layout_editor" type="Spatial"] [node name="building_layout_editor" type="Spatial"]
script = ExtResource( 1 ) script = ExtResource( 1 )
@@ -46,7 +60,8 @@ focus_mode = 2
text = "Interior" text = "Interior"
switch_on_hover = true switch_on_hover = true
[node name="MeshInstance" type="MeshInstance" parent="."] [node name="bg_floor" type="MeshInstance" parent="."]
unique_name_in_owner = true
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0 )
mesh = SubResource( 1 ) mesh = SubResource( 1 )
@@ -97,13 +112,13 @@ size_flags_vertical = 3
unique_name_in_owner = true unique_name_in_owner = true
margin_top = 138.0 margin_top = 138.0
margin_right = 314.0 margin_right = 314.0
margin_bottom = 420.0 margin_bottom = 444.0
[node name="v" type="VBoxContainer" parent="VBoxContainer/socket_editor"] [node name="v" type="VBoxContainer" parent="VBoxContainer/socket_editor"]
margin_left = 7.0 margin_left = 7.0
margin_top = 7.0 margin_top = 7.0
margin_right = 307.0 margin_right = 307.0
margin_bottom = 275.0 margin_bottom = 299.0
[node name="socket_new_element" type="Button" parent="VBoxContainer/socket_editor/v"] [node name="socket_new_element" type="Button" parent="VBoxContainer/socket_editor/v"]
unique_name_in_owner = true unique_name_in_owner = true
@@ -250,11 +265,17 @@ margin_right = 299.0
margin_bottom = 24.0 margin_bottom = 24.0
text = "Set" text = "Set"
[node name="test_element" type="OptionButton" parent="VBoxContainer/socket_editor/v"]
unique_name_in_owner = true
margin_top = 272.0
margin_right = 300.0
margin_bottom = 292.0
[node name="element_editor" type="PanelContainer" parent="VBoxContainer"] [node name="element_editor" type="PanelContainer" parent="VBoxContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_top = 424.0 margin_top = 448.0
margin_right = 314.0 margin_right = 314.0
margin_bottom = 691.0 margin_bottom = 715.0
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/element_editor"] [node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/element_editor"]
margin_left = 7.0 margin_left = 7.0
@@ -304,3 +325,11 @@ columns = 2
[node name="BuildingLayoutEditor" type="BuildingLayoutEditor" parent="."] [node name="BuildingLayoutEditor" type="BuildingLayoutEditor" parent="."]
source = ExtResource( 2 ) source = ExtResource( 2 )
[node name="refcube" type="Spatial" parent="."]
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 )
mesh = SubResource( 3 )
skeleton = NodePath("../..")

View File

@@ -5,6 +5,8 @@
#include <core/engine.h> #include <core/engine.h>
#include <scene/resources/packed_scene.h> #include <scene/resources/packed_scene.h>
#include <scene/3d/mesh_instance.h> #include <scene/3d/mesh_instance.h>
#include <scene/main/viewport.h>
#include <scene/3d/camera.h>
#include <scene/gui/box_container.h> #include <scene/gui/box_container.h>
#include <scene/gui/texture_button.h> #include <scene/gui/texture_button.h>
#include <scene/gui/option_button.h> #include <scene/gui/option_button.h>
@@ -33,6 +35,7 @@ template <class T> T *get_as_node(const String &path)
return ret; return ret;
} }
#define ELEMENT_SOCKETS 16
class ElementData { class ElementData {
public: public:
static ElementData *singleton; static ElementData *singleton;
@@ -51,12 +54,38 @@ public:
String name; String name;
Transform sockets[ELEMENT_SOCKETS]; 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;
};
Vector<struct grid_cell> grid;
protected: protected:
ElementData()
{
grid.resize(grid_size * grid_size);
grid.fill({ "empty", 0 });
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;
}
HashMap<String, struct grid_element_type> element_type; HashMap<String, struct grid_element_type> element_type;
HashMap<String, struct grid_element> elements;
public: public:
void get_key_list(List<String> *keys) void get_element_type_key_list(List<String> *keys)
{ {
element_type.get_key_list(keys); element_type.get_key_list(keys);
} }
@@ -79,7 +108,7 @@ public:
assert(element_type.has(key)); assert(element_type.has(key));
element_type[key].name = name; element_type[key].name = name;
} }
bool has(const String &key) bool has_element_type(const String &key)
{ {
return element_type.has(key); return element_type.has(key);
} }
@@ -93,14 +122,434 @@ public:
{ {
return 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<String> *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<String> keys;
List<String>::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;
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;
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",
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_exterior_grid;
List<Variant> keys;
List<Variant>::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_exterior_grid = config.get_value(
"buildings_layout", "exterior_grid", 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();
}
if (conf_exterior_grid.has("default")) {
Array default_grid = conf_exterior_grid["default"];
if (default_grid.size() == grid_size * grid_size) {
grid.fill({ "empty, 0" });
for (i = 0; i < grid_size * grid_size; i++) {
Dictionary item = default_grid[i];
grid.write[i].element = item["element"];
grid.write[i].rotation =
item["rotation"];
}
}
}
}
}; };
ElementData *ElementData::singleton = nullptr; ElementData *ElementData::singleton = nullptr;
class ElementEditor : public Object {
GDCLASS(ElementEditor, Object)
BuildingLayoutEditor *editor;
String current_element;
int used_socket_count;
HashMap<int, OptionButton *> mesh_select_buttons;
public:
ElementEditor(BuildingLayoutEditor *editor)
: Object()
, editor(editor)
, current_element("")
, used_socket_count(-1)
{
get_as_node<ItemList>("%element_list")
->connect("item_selected", this, "select_element");
get_as_node<Button>("%element_new_element")
->connect("pressed", this, "enter_element_name",
varray(""));
get_as_node<LineEdit>("%element_new_element_name")
->connect("text_entered", this, "enter_element_name");
get_as_node<OptionButton>("%element_type_select")
->connect("item_selected", this, "select_element_type");
}
virtual ~ElementEditor()
{
}
void activate()
{
List<String> element_keys;
List<String>::Element *e;
int i;
if (ElementData::get_singleton()->get_element_type_size() == 0)
print_error("No element types");
get_as_node<Control>("%socket_editor")->hide();
get_as_node<Control>("%element_editor")->show();
get_as_node<LineEdit>("%element_new_element_name")->hide();
get_as_node<ItemList>("%element_list")->clear();
print_line("Restoring UI");
element_keys.clear();
ElementData::get_singleton()->get_element_key_list(
&element_keys);
e = element_keys.front();
while (e) {
get_as_node<ItemList>("%element_list")
->add_item(e->get());
print_line("Added item: " + e->get());
e = e->next();
}
element_keys.clear();
ElementData::get_singleton()->get_element_type_key_list(
&element_keys);
e = element_keys.front();
while (e) {
get_as_node<OptionButton>("%element_type_select")
->add_item(e->get());
print_line("Added item: " + e->get());
e = e->next();
}
get_as_node<ItemList>("%element_list")->select(0);
ItemList *sl = get_as_node<ItemList>("%socket_list");
Control *mb = get_as_node<Control>("%element_mesh_select");
mb->hide();
used_socket_count = sl->get_item_count();
if (mb->get_child_count() == 0) {
for (i = 0; i < used_socket_count; i++) {
String socket_name = sl->get_item_text(i);
Label *label = memnew(Label);
label->set_text(socket_name);
OptionButton *ob = memnew(OptionButton);
mb->add_child(label);
mb->add_child(ob);
List<String> mesh_list;
editor->get_mesh_key_list(&mesh_list);
List<String>::Element *me = mesh_list.front();
ob->clear();
ob->add_item("");
int index = 1;
int selected = 0;
String selected_mesh;
if (ElementData::get_singleton()->has_element(
current_element))
selected_mesh =
ElementData::get_singleton()
->get_element_mesh_name(
current_element,
i);
while (me) {
if (selected_mesh == me->get())
selected = index;
ob->add_item(me->get());
ob->set_item_icon(
index, editor->get_mesh_preview(
me->get()));
mesh_select_buttons[i] = ob;
me = me->next();
index++;
}
ob->select(selected);
ob->connect("item_selected", this,
"mesh_selected", varray(i));
}
}
}
void deactivate()
{
get_as_node<Control>("%element_editor")->hide();
}
void select_element(int element)
{
int i, j;
print_line("selected element: " + itos(element));
String item = get_as_node<ItemList>("%element_list")
->get_item_text(element);
print_line("selected element: " + item);
current_element = item;
String type = ElementData::get_singleton()->get_element_type(
current_element);
Control *mb = get_as_node<Control>("%element_mesh_select");
mb->show();
if (type.length() > 0) {
OptionButton *b = get_as_node<OptionButton>(
"%element_type_select");
for (i = 0; i < b->get_item_count(); i++) {
if (b->get_item_text(i) == type) {
b->select(i);
break;
}
}
} else {
// FIXME: kind of impossible case
OptionButton *b = get_as_node<OptionButton>(
"%element_type_select");
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);
}
editor->visualize_element_type(type, current_element);
}
void mesh_selected(int mesh_idx, int socket)
{
OptionButton *ob = mesh_select_buttons[socket];
String mesh_name =
Object::cast_to<OptionButton>(ob)->get_item_text(
mesh_idx);
if (mesh_name.length() > 0)
ElementData::get_singleton()->set_element_mesh_name(
current_element, socket, mesh_name);
else
ElementData::get_singleton()->set_element_mesh_name(
current_element, socket, mesh_name);
}
void enter_element_name(const String &text)
{
bool added = false;
if (text == "") {
get_as_node<LineEdit>("%element_new_element_name")
->show();
get_as_node<LineEdit>("%element_new_element_name")
->grab_click_focus();
get_as_node<LineEdit>("%element_new_element_name")
->grab_focus();
} else {
String key = text.strip_edges();
assert(!ElementData::get_singleton()->has_element(key));
if (!ElementData::get_singleton()->has_element(key)) {
// FIXME: should use option button to select type
OptionButton *b = get_as_node<OptionButton>(
"%element_type_select");
int selected = b->get_selected();
if (selected >= 0) {
const String &element_type =
b->get_item_text(selected);
ElementData::get_singleton()
->create_element(key,
element_type);
get_as_node<ItemList>("%element_list")
->add_item(key);
added = true;
}
}
assert(added);
get_as_node<LineEdit>("%element_new_element_name")
->set_text("");
get_as_node<LineEdit>("%element_new_element_name")
->release_focus();
get_as_node<LineEdit>("%element_new_element_name")
->hide();
if (added) {
get_as_node<ItemList>("%element_list")
->grab_click_focus();
get_as_node<ItemList>("%element_list")
->grab_focus();
}
}
}
void select_element_type(int element_type)
{
OptionButton *b =
get_as_node<OptionButton>("%element_type_select");
const String &item = b->get_item_text(element_type);
ElementData::get_singleton()->set_element_type(current_element,
item);
editor->visualize_element_type(item, current_element);
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("select_element", "element"),
&ElementEditor::select_element);
ClassDB::bind_method(D_METHOD("mesh_selected", "mesh_idx",
"socket"),
&ElementEditor::mesh_selected);
ClassDB::bind_method(D_METHOD("enter_element_name", "text"),
&ElementEditor::enter_element_name);
ClassDB::bind_method(D_METHOD("select_element_type",
"element_type"),
&ElementEditor::select_element_type);
}
};
class ElementTypeEditor : public Object { class ElementTypeEditor : public Object {
GDCLASS(ElementTypeEditor, Object) GDCLASS(ElementTypeEditor, Object)
BuildingLayoutEditor *editor; BuildingLayoutEditor *editor;
String current_element_type; String current_element_type;
int current_socket; int current_socket;
String test_element;
public: public:
ElementTypeEditor(BuildingLayoutEditor *editor) ElementTypeEditor(BuildingLayoutEditor *editor)
@@ -121,6 +570,8 @@ public:
->connect("pressed", this, "set_socket_offset"); ->connect("pressed", this, "set_socket_offset");
get_as_node<Button>("%socket_editor_rotation_base/set") get_as_node<Button>("%socket_editor_rotation_base/set")
->connect("pressed", this, "set_socket_rotation"); ->connect("pressed", this, "set_socket_rotation");
get_as_node<OptionButton>("%test_element")
->connect("item_selected", this, "select_test_element");
} }
virtual ~ElementTypeEditor() virtual ~ElementTypeEditor()
{ {
@@ -135,6 +586,17 @@ public:
get_as_node<ItemList>("%socket_list")->select(0); get_as_node<ItemList>("%socket_list")->select(0);
// just in case // just in case
select_socket(0); select_socket(0);
editor->visualize_element_type(current_element_type,
test_element);
}
void select_test_element(int element)
{
String item = get_as_node<OptionButton>("%test_element")
->get_item_text(element);
test_element = item;
print_line("selected: " + test_element);
editor->visualize_element_type(current_element_type,
test_element);
} }
void select_socket(int socket) void select_socket(int socket)
{ {
@@ -182,7 +644,8 @@ public:
get_as_node<ItemList>("%element_type_list")->clear(); get_as_node<ItemList>("%element_type_list")->clear();
print_line("Restoring UI"); print_line("Restoring UI");
element_keys.clear(); element_keys.clear();
ElementData::get_singleton()->get_key_list(&element_keys); ElementData::get_singleton()->get_element_type_key_list(
&element_keys);
e = element_keys.front(); e = element_keys.front();
while (e) { while (e) {
get_as_node<ItemList>("%element_type_list") get_as_node<ItemList>("%element_type_list")
@@ -190,6 +653,30 @@ public:
print_line("Added item: " + e->get()); print_line("Added item: " + e->get());
e = e->next(); e = e->next();
} }
element_keys.clear();
ElementData::get_singleton()->get_element_key_list(
&element_keys);
e = element_keys.front();
int selected = -1;
int index = 0;
get_as_node<OptionButton>("%test_element")->clear();
while (e) {
if (e->get() == test_element)
selected = index;
get_as_node<OptionButton>("%test_element")
->add_item(e->get());
print_line("Added test item: " + e->get());
e = e->next();
index++;
}
if (element_keys.size() > 0) {
if (selected >= 0)
get_as_node<OptionButton>("%test_element")
->select(selected);
else
get_as_node<OptionButton>("%test_element")
->select(0);
}
get_as_node<ItemList>("%socket_list")->hide(); get_as_node<ItemList>("%socket_list")->hide();
get_as_node<Control>("%socket_editor")->show(); get_as_node<Control>("%socket_editor")->show();
get_as_node<LineEdit>("%socket_new_element_name")->hide(); get_as_node<LineEdit>("%socket_new_element_name")->hide();
@@ -208,13 +695,16 @@ public:
->grab_focus(); ->grab_focus();
} else { } else {
String key = text.strip_edges(); String key = text.strip_edges();
assert(!ElementData::get_singleton()->has(key)); assert(!ElementData::get_singleton()->has_element_type(
if (!ElementData::get_singleton()->has(key)) { key));
if (!ElementData::get_singleton()->has_element_type(
key)) {
ElementData::get_singleton() ElementData::get_singleton()
->create_element_type(key); ->create_element_type(key);
get_as_node<ItemList>("%element_type_list") get_as_node<ItemList>("%element_type_list")
->add_item(key); ->add_item(key);
assert(ElementData::get_singleton()->has(key)); assert(ElementData::get_singleton()
->has_element_type(key));
added = true; added = true;
} }
assert(added); assert(added);
@@ -255,6 +745,8 @@ public:
xm.origin = Vector3(x, y, z); xm.origin = Vector3(x, y, z);
ElementData::get_singleton()->set_element_type_socket( ElementData::get_singleton()->set_element_type_socket(
current_element_type, current_socket, xm); current_element_type, current_socket, xm);
editor->visualize_element_type(current_element_type,
test_element);
} }
void set_socket_rotation() void set_socket_rotation()
@@ -287,6 +779,8 @@ public:
xm.basis = basis; xm.basis = basis;
ElementData::get_singleton()->set_element_type_socket( ElementData::get_singleton()->set_element_type_socket(
current_element_type, current_socket, xm); current_element_type, current_socket, xm);
editor->visualize_element_type(current_element_type,
test_element);
} }
protected: protected:
@@ -302,6 +796,8 @@ protected:
&ElementTypeEditor::set_socket_offset); &ElementTypeEditor::set_socket_offset);
ClassDB::bind_method(D_METHOD("set_socket_rotation"), ClassDB::bind_method(D_METHOD("set_socket_rotation"),
&ElementTypeEditor::set_socket_rotation); &ElementTypeEditor::set_socket_rotation);
ClassDB::bind_method(D_METHOD("select_test_element", "element"),
&ElementTypeEditor::select_test_element);
} }
}; };
@@ -312,7 +808,6 @@ static std::vector<Object *> editors;
BuildingLayoutEditor::BuildingLayoutEditor() BuildingLayoutEditor::BuildingLayoutEditor()
: meshes_ready(false) : meshes_ready(false)
, current_mode(-1) , current_mode(-1)
, current_element("")
{ {
} }
@@ -438,7 +933,78 @@ Ref<PackedScene> BuildingLayoutEditor::get_source() const
return source; return source;
} }
void BuildingLayoutEditor::get_mesh_key_list(List<String> *keys)
{
meshes.get_key_list(keys);
}
Ref<Texture> BuildingLayoutEditor::get_mesh_preview(const String &key)
{
assert(meshes.has(key));
return meshes[key].preview;
}
void BuildingLayoutEditor::visualize_element_type(const String &key,
const String &test_element)
{
int i;
Spatial *base;
if (!ElementData::get_singleton()->has_element_type(key))
return;
if (!has_node(NodePath("%vis_base"))) {
base = memnew(Spatial);
add_child(base);
base->set_owner(get_owner());
base->set_name("vis_base");
base->set_unique_name_in_owner(true);
assert(has_node(NodePath("%vis_base")));
}
base = Object::cast_to<Spatial>(get_node(NodePath("%vis_base")));
assert(base);
for (i = 0; i < base->get_child_count(); i++) {
base->get_child(i)->queue_delete();
}
print_line("visualizing: " + key + " with " + test_element);
if (!ElementData::get_singleton()->has_element(test_element))
print_line("element " + test_element + " does not exist");
for (i = 0; i < ELEMENT_SOCKETS; i++) {
Transform xform =
ElementData::get_singleton()->get_element_type_socket(
key, i);
String mesh_name = "";
if (!ElementData::get_singleton()->has_element(test_element)) {
switch (i) {
case 0: // floor
mesh_name = "default_floor";
break;
case 1:
case 2:
case 3:
case 4: // wall
mesh_name = "default_wall";
break;
default:
mesh_name = "";
break;
}
} else
mesh_name = ElementData::get_singleton()
->get_element_mesh_name(
test_element, i);
if (mesh_name.length() == 0)
continue;
assert(meshes.has(mesh_name));
MeshInstance *mi = memnew(MeshInstance);
mi->set_mesh(meshes[mesh_name].mesh);
mi->set_transform(xform);
base->call_deferred("add_child", mi);
print_line("displaying: " + mesh_name);
}
}
static ElementTypeEditor *etype_editor; static ElementTypeEditor *etype_editor;
static ElementEditor *element_editor;
void BuildingLayoutEditor::_notification(int which) void BuildingLayoutEditor::_notification(int which)
{ {
@@ -448,7 +1014,9 @@ void BuildingLayoutEditor::_notification(int which)
if (Engine::get_singleton()->is_editor_hint()) if (Engine::get_singleton()->is_editor_hint())
return; return;
etype_editor = memnew(ElementTypeEditor(this)); etype_editor = memnew(ElementTypeEditor(this));
element_editor = memnew(ElementEditor(this));
editors.push_back(etype_editor); editors.push_back(etype_editor);
editors.push_back(element_editor);
connect_signals(); connect_signals();
if (!meshes_ready) { if (!meshes_ready) {
prepare_meshes(); prepare_meshes();
@@ -459,6 +1027,9 @@ void BuildingLayoutEditor::_notification(int which)
case NOTIFICATION_EXIT_TREE: case NOTIFICATION_EXIT_TREE:
for (i = 0; i < (int)editors.size(); i++) for (i = 0; i < (int)editors.size(); i++)
memdelete(editors[i]); memdelete(editors[i]);
Node *vis = get_node(NodePath("%vis_base"));
if (vis)
vis->queue_delete();
} }
} }
@@ -536,14 +1107,8 @@ void BuildingLayoutEditor::_bind_methods()
&BuildingLayoutEditor::get_source); &BuildingLayoutEditor::get_source);
ClassDB::bind_method(D_METHOD("select_mode", "mode"), ClassDB::bind_method(D_METHOD("select_mode", "mode"),
&BuildingLayoutEditor::select_mode); &BuildingLayoutEditor::select_mode);
ClassDB::bind_method(D_METHOD("enter_element_name", "text"),
&BuildingLayoutEditor::enter_element_name);
ClassDB::bind_method(D_METHOD("select_element", "element"),
&BuildingLayoutEditor::select_element);
ClassDB::bind_method(D_METHOD("menu_control"), ClassDB::bind_method(D_METHOD("menu_control"),
&BuildingLayoutEditor::menu_control); &BuildingLayoutEditor::menu_control);
ClassDB::bind_method(D_METHOD("mesh_selected", "mesh_idx", "socket"),
&BuildingLayoutEditor::mesh_selected);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "source", ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "source",
PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"),
"set_source", "get_source"); "set_source", "get_source");
@@ -554,13 +1119,7 @@ void BuildingLayoutEditor::connect_signals()
int i; int i;
if (Engine::get_singleton()->is_editor_hint()) if (Engine::get_singleton()->is_editor_hint())
return; return;
get_as_node<ItemList>("%element_list")
->connect("item_selected", this, "select_element");
get_as_node<Button>("%element_new_element")
->connect("pressed", this, "enter_element_name", varray(""));
get_as_node<LineEdit>("%element_new_element_name")
->connect("text_entered", this, "enter_element_name");
Node *menu_panel = get_node(NodePath("%menu_panel")); Node *menu_panel = get_node(NodePath("%menu_panel"));
for (i = 0; i < menu_panel->get_child_count(); i++) { for (i = 0; i < menu_panel->get_child_count(); i++) {
Node *m = menu_panel->get_child(i); Node *m = menu_panel->get_child(i);
@@ -571,11 +1130,9 @@ void BuildingLayoutEditor::connect_signals()
void BuildingLayoutEditor::select_mode(int mode) void BuildingLayoutEditor::select_mode(int mode)
{ {
int i;
if (Engine::get_singleton()->is_editor_hint()) if (Engine::get_singleton()->is_editor_hint())
return; return;
List<String> element_keys; List<String> element_keys;
List<String>::Element *e;
print_line("set mode: " + itos(mode)); print_line("set mode: " + itos(mode));
if (Engine::get_singleton()->is_editor_hint()) if (Engine::get_singleton()->is_editor_hint())
return; return;
@@ -590,124 +1147,44 @@ void BuildingLayoutEditor::select_mode(int mode)
switch (mode) { switch (mode) {
case 0: case 0:
etype_editor->deactivate(); etype_editor->deactivate();
get_as_node<Control>("%element_editor")->hide(); element_editor->deactivate();
if (elements.size() == 0) get_as_node<Spatial>("%bg_floor")->show();
{
// delete children of bg_floor
int i;
for (i = 0;
i < get_as_node<Spatial>("%bg_floor")
->get_child_count();
i++) {
get_as_node<Spatial>("%bg_floor")
->get_child(i)
->queue_delete();
}
}
get_viewport()->get_camera()->set_global_translation(
Vector3(-25, 25, 25));
if (ElementData::get_singleton()->get_element_size() ==
0)
print_error("No elements"); print_error("No elements");
break; break;
case 1: case 1:
get_as_node<Spatial>("%bg_floor")->hide();
get_as_node<Spatial>("%refcube")
->set_global_transform(Transform());
get_viewport()->get_camera()->set_global_translation(
Vector3(-10, 10, 10));
element_editor->deactivate();
etype_editor->activate(); etype_editor->activate();
get_as_node<Control>("%element_editor")->hide();
element_keys.clear(); element_keys.clear();
break; break;
case 2: case 2:
get_as_node<Spatial>("%bg_floor")->hide();
get_as_node<Spatial>("%refcube")
->set_global_transform(Transform());
get_viewport()->get_camera()->set_global_translation(
Vector3(-10, 10, 10));
etype_editor->deactivate(); etype_editor->deactivate();
if (ElementData::get_singleton() element_editor->activate();
->get_element_type_size() == 0)
print_error("No element types");
get_as_node<Control>("%socket_editor")->hide();
get_as_node<Control>("%element_editor")->show();
get_as_node<LineEdit>("%element_new_element_name")
->hide();
get_as_node<ItemList>("%element_list")->clear();
print_line("Restoring UI");
element_keys.clear();
elements.get_key_list(&element_keys);
e = element_keys.front();
while (e) {
get_as_node<ItemList>("%element_list")
->add_item(e->get());
print_line("Added item: " + e->get());
e = e->next();
}
element_keys.clear();
ElementData::get_singleton()->get_key_list(
&element_keys);
e = element_keys.front();
while (e) {
get_as_node<OptionButton>(
"%element_type_select")
->add_item(e->get());
print_line("Added item: " + e->get());
e = e->next();
}
get_as_node<ItemList>("%element_list")->select(0);
ItemList *sl = get_as_node<ItemList>("%socket_list");
Control *mb =
get_as_node<Control>("%element_mesh_select");
mb->hide();
used_socket_count = sl->get_item_count();
if (mb->get_child_count() == 0) {
for (i = 0; i < used_socket_count; i++) {
String socket_name =
sl->get_item_text(i);
Label *label = memnew(Label);
label->set_text(socket_name);
OptionButton *ob = memnew(OptionButton);
mb->add_child(label);
mb->add_child(ob);
List<String> mesh_list;
meshes.get_key_list(&mesh_list);
List<String>::Element *me =
mesh_list.front();
ob->clear();
ob->add_item("");
int index = 1;
int selected = 0;
String selected_mesh;
if (elements.has(current_element))
selected_mesh =
elements[current_element]
.mesh_names[i];
while (me) {
if (selected_mesh == me->get())
selected = index;
ob->add_item(me->get());
ob->set_item_icon(
index,
meshes[me->get()]
.preview);
mesh_select_buttons[i] = ob;
me = me->next();
index++;
}
ob->select(selected);
ob->connect("item_selected", this,
"mesh_selected", varray(i));
}
}
// select_element(0);
break;
}
}
}
void BuildingLayoutEditor::enter_element_name(const String &text)
{
bool added = false;
if (text == "") {
get_as_node<LineEdit>("%element_new_element_name")->show();
get_as_node<LineEdit>("%element_new_element_name")
->grab_click_focus();
get_as_node<LineEdit>("%element_new_element_name")->grab_focus();
} else {
String key = text.strip_edges();
assert(!elements.has(key));
if (!elements.has(key)) {
struct grid_element g;
g.name = key;
elements[key] = g;
get_as_node<ItemList>("%element_list")->add_item(key);
added = true;
}
assert(added);
get_as_node<LineEdit>("%element_new_element_name")->set_text("");
get_as_node<LineEdit>("%element_new_element_name")
->release_focus();
get_as_node<LineEdit>("%element_new_element_name")->hide();
if (added) {
get_as_node<ItemList>("%element_list")
->grab_click_focus();
get_as_node<ItemList>("%element_list")->grab_focus();
} }
} }
} }
@@ -734,61 +1211,8 @@ void BuildingLayoutEditor::menu_control(int id)
} }
} }
void BuildingLayoutEditor::select_element(int element)
{
int i, j;
print_line("selected element: " + itos(element));
String item =
get_as_node<ItemList>("%element_list")->get_item_text(element);
print_line("selected element: " + item);
current_element = item;
String type = elements[current_element].type;
Control *mb = get_as_node<Control>("%element_mesh_select");
mb->show();
if (type.length() > 0) {
OptionButton *b =
get_as_node<OptionButton>("%element_type_select");
for (i = 0; i < b->get_item_count(); i++) {
if (b->get_item_text(i) == type) {
b->select(i);
break;
}
}
} else {
OptionButton *b =
get_as_node<OptionButton>("%element_type_select");
elements[current_element].type = b->get_item_text(0);
}
int selected = 0;
for (i = 0; i < used_socket_count; i++) {
String selected_mesh = elements[current_element].mesh_names[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);
}
}
void BuildingLayoutEditor::mesh_selected(int mesh_idx, int socket)
{
OptionButton *ob = mesh_select_buttons[socket];
String mesh_name =
Object::cast_to<OptionButton>(ob)->get_item_text(mesh_idx);
if (mesh_name.length() > 0) {
elements[current_element].mesh_names[socket] = mesh_name;
} else {
elements[current_element].mesh_names[socket] = "";
}
}
void BuildingLayoutEditor::save_data() void BuildingLayoutEditor::save_data()
{ {
print_line("save_data"); print_line("save_data");
ElementData::get_singleton()->save_data();
} }

View File

@@ -13,18 +13,8 @@ class BuildingLayoutEditor : public Node {
Ref<Texture> preview; Ref<Texture> preview;
}; };
HashMap<String, struct mesh_data> meshes; HashMap<String, struct mesh_data> meshes;
HashMap<int, OptionButton *> mesh_select_buttons;
int used_socket_count;
#define ELEMENT_SOCKETS 16
struct grid_element {
String name;
String type;
String mesh_names[ELEMENT_SOCKETS];
};
HashMap<String, struct grid_element> elements;
bool meshes_ready; bool meshes_ready;
int current_mode; int current_mode;
String current_element;
public: public:
BuildingLayoutEditor(); BuildingLayoutEditor();
@@ -33,6 +23,10 @@ public:
Vector<Transform> *p_transforms, int p_preview_size); Vector<Transform> *p_transforms, int p_preview_size);
void set_source(const Ref<PackedScene> &src); void set_source(const Ref<PackedScene> &src);
Ref<PackedScene> get_source() const; Ref<PackedScene> get_source() const;
void get_mesh_key_list(List<String> *keys);
Ref<Texture> get_mesh_preview(const String &key);
void visualize_element_type(const String &key,
const String &test_element);
protected: protected:
void _notification(int which); void _notification(int which);
@@ -41,12 +35,6 @@ protected:
static void _bind_methods(); static void _bind_methods();
void connect_signals(); void connect_signals();
void select_mode(int mode); void select_mode(int mode);
void enter_element_name(const String &text);
void select_socket(int socket);
void set_socket_offset();
void set_socket_rotation();
void menu_control(int id); void menu_control(int id);
void select_element(int element);
void mesh_selected(int mesh_idx, int socket);
void save_data(); void save_data();
}; };