Multiple levels support

This commit is contained in:
2024-10-08 04:31:36 +03:00
parent f62dbbf505
commit 69b62c8c97
3 changed files with 1767 additions and 100 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,9 @@ size = Vector3( 4, 8, 4 )
[sub_resource type="SpatialMaterial" id=4] [sub_resource type="SpatialMaterial" id=4]
flags_transparent = true flags_transparent = true
albedo_color = Color( 1, 1, 1, 0.654902 ) flags_unshaded = true
flags_do_not_receive_shadows = true
albedo_color = Color( 1, 1, 1, 0.462745 )
[sub_resource type="CubeMesh" id=1] [sub_resource type="CubeMesh" id=1]
material = SubResource( 4 ) material = SubResource( 4 )
@@ -35,7 +37,7 @@ margin_bottom = 20.0
margin_right = 35.0 margin_right = 35.0
margin_bottom = 20.0 margin_bottom = 20.0
text = "File" text = "File"
items = [ "Save", null, 0, false, false, 100, 0, null, "", false ] items = [ "Save", null, 0, false, false, 100, 0, null, "", false, "Build Mesh Library", null, 0, false, false, 101, 0, null, "", false ]
switch_on_hover = true switch_on_hover = true
[node name="ElementMenu" type="MenuButton" parent="menu_panel"] [node name="ElementMenu" type="MenuButton" parent="menu_panel"]
@@ -377,22 +379,20 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 4, -2 )
mesh = SubResource( 3 ) mesh = SubResource( 3 )
skeleton = NodePath("../..") skeleton = NodePath("../..")
[node name="RemoteTransform" type="RemoteTransform" parent="."] [node name="bg_floor_base" type="Spatial" parent="."]
remote_path = NodePath("../bg_floor") unique_name_in_owner = true
update_rotation = false
update_scale = false
[node name="bg_floor_base" type="MeshInstance" parent="RemoteTransform"] [node name="bg_floor_mi" type="MeshInstance" parent="bg_floor_base"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -0.5, -2 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -0.5, -2 )
mesh = SubResource( 1 ) mesh = SubResource( 1 )
skeleton = NodePath("../..") skeleton = NodePath("../..")
[node name="Area" type="Area" parent="RemoteTransform/bg_floor_base"] [node name="Area" type="Area" parent="bg_floor_base/bg_floor_mi"]
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 )
collision_layer = 49152 collision_layer = 49152
collision_mask = 49152 collision_mask = 49152
monitoring = false monitoring = false
[node name="CollisionShape" type="CollisionShape" parent="RemoteTransform/bg_floor_base/Area"] [node name="CollisionShape" type="CollisionShape" parent="bg_floor_base/bg_floor_mi/Area"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
shape = SubResource( 5 ) shape = SubResource( 5 )

View File

@@ -101,7 +101,8 @@ public:
int rotation; int rotation;
}; };
struct grid_layouts {}; struct grid_layouts {};
struct grid_layout { struct grid_layout {};
struct grid_layout_base {
int floor_count; int floor_count;
}; };
struct grid_layout_exterior {}; struct grid_layout_exterior {};
@@ -159,23 +160,21 @@ public:
flecs::entity layout = flecs::entity layout =
ecs.entity(key.ascii().ptr()).child_of(top); ecs.entity(key.ascii().ptr()).child_of(top);
// one floor by default // one floor by default
layout.set<grid_layout>({ 0 }); layout.add<struct grid_layout>();
flecs::entity extr = ecs.entity("exterior").child_of(layout); flecs::entity extr = ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>(); extr.add<grid_layout_exterior>();
flecs::entity intr = ecs.entity("interior").child_of(layout); flecs::entity intr = ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>(); intr.add<grid_layout_interior>();
intr.set<grid_layout_base>({ 0 });
extr.set<grid_layout_base>({ 0 });
} }
void create_new_exterior_floor(const String &key) void create_new_exterior_floor(const String &key)
{ {
int i; int i;
flecs::entity top = ecs.lookup("grid_layouts"); flecs::entity ext = get_base(key, true);
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()); assert(ext.is_valid());
struct grid_layout_base *l = ext.get_mut<grid_layout_base>();
int floor = l->floor_count;
flecs::entity fl = flecs::entity fl =
ecs.entity(("floor_" + itos(floor)).ascii().ptr()) ecs.entity(("floor_" + itos(floor)).ascii().ptr())
.child_of(ext); .child_of(ext);
@@ -192,14 +191,10 @@ public:
void create_new_interior_floor(const String &key) void create_new_interior_floor(const String &key)
{ {
int i; int i;
flecs::entity top = ecs.lookup("grid_layouts"); flecs::entity intr = get_base(key, false);
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()); assert(intr.is_valid());
struct grid_layout_base *l = intr.get_mut<grid_layout_base>();
int floor = l->floor_count;
flecs::entity fl = flecs::entity fl =
ecs.entity(("floor_" + itos(floor)).ascii().ptr()) ecs.entity(("floor_" + itos(floor)).ascii().ptr())
.child_of(intr); .child_of(intr);
@@ -217,29 +212,63 @@ public:
{ {
return grid_size; return grid_size;
} }
inline flecs::entity get_grid_entity(const String &key, bool exterior, flecs::entity get_base(const String &key, bool exterior) const
int fl, int i) const
{ {
flecs::entity top = ecs.lookup("grid_layouts"); flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid()); assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr()); flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid()); 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; flecs::entity base;
if (exterior) if (exterior)
base = layout.lookup("exterior"); base = layout.lookup("exterior");
else else
base = layout.lookup("interior"); 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()); assert(base.is_valid());
String floor_key = "floor_" + itos(fl); 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<grid_floor_item>({ 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); String item_key = "item_" + itos(i);
flecs::entity item_data = base.lookup( flecs::entity item_data = base.lookup(item_key.ascii().ptr());
(floor_key + "::" + item_key).ascii().ptr());
if (!item_data.is_valid()) if (!item_data.is_valid())
print_error("lookup failed: " + floor_key + print_error("lookup failed: " + item_key);
"::" + item_key);
assert(item_data.is_valid()); assert(item_data.is_valid());
return item_data; return item_data;
} }
@@ -272,6 +301,7 @@ public:
} }
Spatial *get_grid_node(const String &key, bool exterior, int fl, int i) 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); flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
if (!item_data.has<struct grid_floor_item_node>()) { if (!item_data.has<struct grid_floor_item_node>()) {
Spatial *sp = memnew(Spatial); Spatial *sp = memnew(Spatial);
@@ -284,7 +314,7 @@ public:
sp->set_transform(Transform( sp->set_transform(Transform(
Basis().rotated(Vector3(0, 1, 0), Basis().rotated(Vector3(0, 1, 0),
Math_PI * rotation / 2.0f), Math_PI * rotation / 2.0f),
Vector3((x - 4) * 4, 0, (z - 4) * 4) - Vector3((x - 4) * 4, 1 + 5 * fl, (z - 4) * 4) -
get_as_node<Spatial>("%bg_floor") get_as_node<Spatial>("%bg_floor")
->get_transform() ->get_transform()
.origin)); .origin));
@@ -295,14 +325,8 @@ public:
const Vector3 &position) const Vector3 &position)
{ {
int i; int i;
String full_key = "grid_layouts::" + key; assert(has_floor(key, exterior, fl));
if (exterior) flecs::entity floor_e = get_floor(key, exterior, fl);
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()); assert(floor_e.is_valid());
int selected = -1; int selected = -1;
float dst = Math_INF; float dst = Math_INF;
@@ -416,13 +440,15 @@ public:
flecs::entity layout = flecs::entity layout =
ecs.entity(layout_name.ascii().ptr()) ecs.entity(layout_name.ascii().ptr())
.child_of(top); .child_of(top);
layout.set<grid_layout>({ 0 }); layout.add<grid_layout>();
flecs::entity extr = flecs::entity extr =
ecs.entity("exterior").child_of(layout); ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>(); extr.add<grid_layout_exterior>();
extr.set<grid_layout_base>({ 0 });
flecs::entity intr = flecs::entity intr =
ecs.entity("interior").child_of(layout); ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>(); intr.add<grid_layout_interior>();
intr.set<grid_layout_base>({ 0 });
Dictionary store_layout = store[e->get()]; Dictionary store_layout = store[e->get()];
Dictionary store_interior = store_layout["interior"]; Dictionary store_interior = store_layout["interior"];
Dictionary store_exterior = store_layout["exterior"]; Dictionary store_exterior = store_layout["exterior"];
@@ -461,8 +487,8 @@ public:
{ index, element, { index, element,
rotation }); rotation });
} }
struct grid_layout *l = layout.get_mut< struct grid_layout_base *l = intr.get_mut<
struct grid_layout>(); struct grid_layout_base>();
l->floor_count++; l->floor_count++;
} }
} }
@@ -496,8 +522,8 @@ public:
{ index, element, { index, element,
rotation }); rotation });
} }
struct grid_layout *l = layout.get_mut< struct grid_layout_base *l = extr.get_mut<
struct grid_layout>(); struct grid_layout_base>();
l->floor_count++; l->floor_count++;
} }
} }
@@ -698,20 +724,6 @@ public:
e = e->next(); e = e->next();
} }
unserialize_layouts(conf_grid_layouts); 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) {
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"];
}
}
}
#endif
} }
}; };
ElementData *ElementData::singleton = nullptr; ElementData *ElementData::singleton = nullptr;
@@ -720,17 +732,29 @@ class LayoutEditor : public Object {
GDCLASS(LayoutEditor, Object) GDCLASS(LayoutEditor, Object)
BuildingLayoutEditor *editor; BuildingLayoutEditor *editor;
String grid_elements; String grid_elements;
String level_value;
int current_cell; int current_cell;
String current_layout;
bool is_exterior;
int current_floor;
public: public:
LayoutEditor(BuildingLayoutEditor *editor) LayoutEditor(BuildingLayoutEditor *editor)
: Object() : Object()
, editor(editor) , editor(editor)
, grid_elements("%grid_elements") , grid_elements("%grid_elements")
, level_value("%level_value")
, current_cell(-1) , current_cell(-1)
, current_layout("default")
, is_exterior(true)
, current_floor(0)
{ {
get_as_node<OptionButton>(grid_elements) get_as_node<OptionButton>(grid_elements)
->connect("item_selected", this, "select_grid_element"); ->connect("item_selected", this, "select_grid_element");
SpinBox *sb = get_as_node<SpinBox>(level_value);
sb->connect("value_changed", this, "set_current_floor");
sb->set_min(-6);
sb->set_max(6);
} }
virtual ~LayoutEditor() virtual ~LayoutEditor()
{ {
@@ -749,28 +773,35 @@ public:
->get_child(i) ->get_child(i)
->queue_delete(); ->queue_delete();
} }
List<String> layout_keys;
int grid_size = int grid_size =
ElementData::get_singleton()->get_grid_size(); ElementData::get_singleton()->get_grid_size();
assert(grid_size > 0); assert(grid_size > 0);
const String layout_key = "default"; int fl;
bool exterior = true; for (fl = -7; fl < 7; fl++) {
int floor = 0; if (!ElementData::get_singleton()->has_floor(
current_layout, is_exterior, fl))
continue;
for (i = 0; i < grid_size * grid_size; i++) { for (i = 0; i < grid_size * grid_size; i++) {
Spatial *node = Spatial *node =
ElementData::get_singleton() ElementData::get_singleton()
->get_grid_node(layout_key, ->get_grid_node(
exterior, floor, current_layout,
is_exterior, fl,
i); i);
String element = String element =
ElementData::get_singleton() ElementData::get_singleton()
->get_grid_element(layout_key, ->get_grid_element(
exterior, current_layout,
floor, i); is_exterior, fl,
editor->visualize_element_at(element, node); i);
editor->visualize_element_at(element,
node);
print_line("element: " + element); print_line("element: " + element);
} }
} }
}
editor->get_viewport()->get_camera()->set_global_translation( editor->get_viewport()->get_camera()->set_global_translation(
Vector3(-14, 23, 32)); Vector3(-14, 23, 32));
List<String> element_keys; List<String> element_keys;
@@ -817,27 +848,27 @@ public:
Vector3 proj = result.position; Vector3 proj = result.position;
Transform xf( Transform xf(
Basis(), Basis(),
Vector3(Math::stepify(proj.x, 4.0f), 0, Vector3(Math::stepify(proj.x, 4.0f),
0 + current_floor * 5,
Math::stepify(proj.z, 4.0f))); Math::stepify(proj.z, 4.0f)));
get_as_node<Spatial>("%refcube") get_as_node<Spatial>("%refcube")
->set_global_transform(xf); ->set_global_transform(xf);
String layout_key = "default";
bool exterior = true;
int floor = 0;
int selected = int selected =
ElementData::get_singleton() ElementData::get_singleton()
->get_closest_node_on_floor( ->get_closest_node_on_floor(
layout_key, exterior, current_layout,
floor, xf.origin); is_exterior,
current_floor,
xf.origin);
if (selected >= 0) { if (selected >= 0) {
current_cell = selected; current_cell = selected;
get_as_node<Spatial>("%refcube") get_as_node<Spatial>("%refcube")
->set_global_transform( ->set_global_transform(
ElementData::get_singleton() ElementData::get_singleton()
->get_grid_node( ->get_grid_node(
layout_key, current_layout,
exterior, is_exterior,
floor, current_floor,
current_cell) current_cell)
->get_global_transform()); ->get_global_transform());
print_line( print_line(
@@ -845,9 +876,9 @@ public:
"pos: " + "pos: " +
(ElementData::get_singleton() (ElementData::get_singleton()
->get_grid_node( ->get_grid_node(
layout_key, current_layout,
exterior, is_exterior,
floor, current_floor,
current_cell) current_cell)
->get_global_transform() ->get_global_transform()
.origin .origin
@@ -855,8 +886,9 @@ public:
String element = String element =
ElementData::get_singleton() ElementData::get_singleton()
->get_grid_element( ->get_grid_element(
layout_key, current_layout,
exterior, floor, is_exterior,
current_floor,
current_cell); current_cell);
select_control_item<OptionButton>( select_control_item<OptionButton>(
"%grid_elements", element); "%grid_elements", element);
@@ -864,28 +896,38 @@ public:
} }
} }
} }
void set_current_floor(float value)
{
current_floor = (int)value;
Transform base = get_as_node<Spatial>("%bg_floor_base")
->get_global_transform();
base.origin.y = current_floor * 5.0f;
get_as_node<Spatial>("%bg_floor_base")
->set_global_transform(base);
ElementData::get_singleton()->ensure_floor(
current_layout, is_exterior, current_floor);
}
void select_grid_element(int index) void select_grid_element(int index)
{ {
String layout_key = "default";
bool exterior = true;
int floor = 0;
print_line("selected: " + itos(current_cell) + " " + print_line("selected: " + itos(current_cell) + " " +
itos(index)); itos(index));
const String &element = const String &element =
get_as_node<OptionButton>("%grid_elements") get_as_node<OptionButton>("%grid_elements")
->get_item_text(index); ->get_item_text(index);
ElementData::get_singleton()->set_grid_element( ElementData::get_singleton()->set_grid_element(
layout_key, exterior, floor, current_cell, element); current_layout, is_exterior, current_floor,
current_cell, element);
editor->visualize_element_at( editor->visualize_element_at(
element, element, ElementData::get_singleton()->get_grid_node(
ElementData::get_singleton()->get_grid_node( current_layout, is_exterior,
layout_key, exterior, floor, current_cell)); current_floor, current_cell));
} }
static void _bind_methods() static void _bind_methods()
{ {
ClassDB::bind_method(D_METHOD("select_grid_element", "index"), ClassDB::bind_method(D_METHOD("select_grid_element", "index"),
&LayoutEditor::select_grid_element); &LayoutEditor::select_grid_element);
ClassDB::bind_method(D_METHOD("set_current_floor", "value"),
&LayoutEditor::set_current_floor);
} }
}; };