Now creating MeshLibrary for buildings

This commit is contained in:
2024-10-16 01:10:15 +03:00
parent b6b5fdada9
commit 844056de64
7 changed files with 194 additions and 25 deletions

View File

@@ -118,6 +118,21 @@ elements={
"mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ], "mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "test_element", "name": "test_element",
"type": "e1" "type": "e1"
},
"top_single_tile": {
"mesh_names": [ "exterior_roof1-top2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "top_single_tile",
"type": "roof_bottom"
},
"top_single_tile_side": {
"mesh_names": [ "exterior_roof1-top-side", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "top_single_tile_side",
"type": "roof_bottom"
},
"top_single_tile_side2": {
"mesh_names": [ "exterior_roof1-top-side2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
"name": "top_single_tile_side2",
"type": "roof_bottom"
} }
} }
grid_layouts={ grid_layouts={
@@ -2832,7 +2847,7 @@ grid_layouts={
"index": 26, "index": 26,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 27, "index": 27,
"rotation": 3 "rotation": 3
}, { }, {
@@ -2860,7 +2875,7 @@ grid_layouts={
"index": 33, "index": 33,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 34, "index": 34,
"rotation": 1 "rotation": 1
}, { }, {
@@ -2868,7 +2883,7 @@ grid_layouts={
"index": 35, "index": 35,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 36, "index": 36,
"rotation": 3 "rotation": 3
}, { }, {
@@ -2896,7 +2911,7 @@ grid_layouts={
"index": 42, "index": 42,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 43, "index": 43,
"rotation": 1 "rotation": 1
}, { }, {
@@ -2904,7 +2919,7 @@ grid_layouts={
"index": 44, "index": 44,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 45, "index": 45,
"rotation": 3 "rotation": 3
}, { }, {
@@ -2932,7 +2947,7 @@ grid_layouts={
"index": 51, "index": 51,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 52, "index": 52,
"rotation": 1 "rotation": 1
}, { }, {
@@ -2940,7 +2955,7 @@ grid_layouts={
"index": 53, "index": 53,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 54, "index": 54,
"rotation": 3 "rotation": 3
}, { }, {
@@ -2968,7 +2983,7 @@ grid_layouts={
"index": 60, "index": 60,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 61, "index": 61,
"rotation": 1 "rotation": 1
}, { }, {
@@ -2976,7 +2991,7 @@ grid_layouts={
"index": 62, "index": 62,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 63, "index": 63,
"rotation": 3 "rotation": 3
}, { }, {
@@ -3004,7 +3019,7 @@ grid_layouts={
"index": 69, "index": 69,
"rotation": 0 "rotation": 0
}, { }, {
"element": "side_wall", "element": "side_wall_no_floor",
"index": 70, "index": 70,
"rotation": 1 "rotation": 1
}, { }, {
@@ -3157,7 +3172,7 @@ grid_layouts={
"index": 26, "index": 26,
"rotation": 0 "rotation": 0
}, { }, {
"element": "roof_corner2", "element": "roof_mid_corner2",
"index": 27, "index": 27,
"rotation": 2 "rotation": 2
}, { }, {
@@ -3879,35 +3894,35 @@ grid_layouts={
"index": 44, "index": 44,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile_side",
"index": 45, "index": 45,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 46, "index": 46,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 47, "index": 47,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 48, "index": 48,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 49, "index": 49,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 50, "index": 50,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile",
"index": 51, "index": 51,
"rotation": 0 "rotation": 0
}, { }, {
"element": "empty", "element": "top_single_tile_side2",
"index": 52, "index": 52,
"rotation": 0 "rotation": 0
}, { }, {

View File

@@ -6,6 +6,7 @@
#include <core/os/input.h> #include <core/os/input.h>
#include <scene/resources/packed_scene.h> #include <scene/resources/packed_scene.h>
#include <scene/resources/surface_tool.h> #include <scene/resources/surface_tool.h>
#include <scene/resources/mesh_library.h>
#include <scene/3d/mesh_instance.h> #include <scene/3d/mesh_instance.h>
#include <scene/main/viewport.h> #include <scene/main/viewport.h>
#include <scene/3d/camera.h> #include <scene/3d/camera.h>
@@ -1078,9 +1079,8 @@ void BuildingLayoutEditor::visualize_element_type(const String &key,
} }
void BuildingLayoutEditor::visualize_element_at(const String &element, void BuildingLayoutEditor::visualize_element_at(const String &element,
Spatial *node) Spatial *node) const
{ {
int i;
if (!ElementData::get_singleton()->has_element(element)) if (!ElementData::get_singleton()->has_element(element))
return; return;
const String &element_type = const String &element_type =
@@ -1148,6 +1148,93 @@ Ref<Mesh> BuildingLayoutEditor::get_element_mesh(const String &element) const
assert(ret.is_valid()); assert(ret.is_valid());
return ret; return ret;
} }
Ref<Mesh>
BuildingLayoutEditor::get_layout_exterior_mesh(const String &layout) const
{
Ref<ArrayMesh> ret;
ret.instance();
ret->set_storage_mode(Mesh::STORAGE_MODE_CPU);
SurfaceTool sf;
Ref<Material> mat;
bool exterior = true;
int i;
int grid_size = ElementData::get_singleton()->get_grid_size();
assert(grid_size > 0);
int fl;
for (fl = -7; fl < 7; fl++) {
if (!ElementData::get_singleton()->has_floor(layout, exterior,
fl))
continue;
for (i = 0; i < grid_size * grid_size; i++) {
Spatial *node =
ElementData::get_singleton()->get_grid_node(
layout, exterior, fl, i);
assert(node);
String element =
ElementData::get_singleton()->get_grid_element(
layout, exterior, fl, i);
assert(element.length() > 0);
Ref<Mesh> src =
ElementData::get_singleton()->get_element_mesh(
element);
assert(src.is_valid());
src->set_storage_mode(Mesh::STORAGE_MODE_CPU);
}
}
for (fl = -7; fl < 7; fl++) {
if (!ElementData::get_singleton()->has_floor(layout, exterior,
fl))
continue;
for (i = 0; i < grid_size * grid_size; i++) {
Spatial *node =
ElementData::get_singleton()->get_grid_node(
layout, exterior, fl, i);
assert(node);
String element =
ElementData::get_singleton()->get_grid_element(
layout, exterior, fl, i);
assert(element.length() > 0);
Ref<Mesh> src =
ElementData::get_singleton()->get_element_mesh(
element);
assert(src.is_valid());
if (src->get_surface_count() == 1) {
Transform xform = node->get_transform();
if (!mat.is_valid())
mat = src->surface_get_material(0);
sf.append_from(src, 0, xform);
}
}
}
for (fl = -7; fl < 7; fl++) {
if (!ElementData::get_singleton()->has_floor(layout, exterior,
fl))
continue;
for (i = 0; i < grid_size * grid_size; i++) {
Spatial *node =
ElementData::get_singleton()->get_grid_node(
layout, exterior, fl, i);
assert(node);
String element =
ElementData::get_singleton()->get_grid_element(
layout, exterior, fl, i);
assert(element.length() > 0);
Ref<Mesh> src =
ElementData::get_singleton()->get_element_mesh(
element);
assert(src.is_valid());
src->set_storage_mode(Mesh::STORAGE_MODE_GPU);
}
}
Array arr = sf.commit_to_arrays();
ret->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr, Array(),
Mesh::ARRAY_COMPRESS_DEFAULT);
ret->surface_set_material(0, mat);
ret->set_storage_mode(Mesh::STORAGE_MODE_CPU_AND_GPU);
assert(ret.is_valid());
return ret;
}
void BuildingLayoutEditor::update_element_meshes() void BuildingLayoutEditor::update_element_meshes()
{ {
List<String> keys; List<String> keys;
@@ -1164,6 +1251,52 @@ void BuildingLayoutEditor::update_element_meshes()
} }
} }
void BuildingLayoutEditor::update_layout_meshes()
{
int i;
Ref<MeshLibrary> ml;
List<String> keys;
List<String>::Element *e;
print_line("update_layout_meshes");
ElementData::get_singleton()->get_grid_layouts_key_list(&keys);
e = keys.front();
ml.instance();
Vector<Ref<Mesh> > for_previews;
Vector<Transform> for_previews_xform;
int lod = 0;
while (e) {
print_line("update_layout_meshes: " + e->get());
String item_name = e->get() + "_lod" + itos(lod);
int id = ml->get_last_unused_item_id();
ml->create_item(id);
Ref<Mesh> mesh = get_layout_exterior_mesh(e->get());
assert(mesh.is_valid());
Ref<Shape> shape = mesh->create_trimesh_shape();
assert(shape.is_valid());
ml->set_item_name(id, item_name);
ml->set_item_mesh(id, mesh);
Vector<MeshLibrary::ShapeData> shapes;
MeshLibrary::ShapeData shape_data;
shape_data.shape = shape;
shape_data.local_transform = Transform();
shapes.push_back(shape_data);
ml->set_item_shapes(id, shapes);
for_previews.push_back(mesh);
for_previews_xform.push_back(Transform());
e = e->next();
}
Vector<Ref<Texture> > previews =
make_mesh_previews(for_previews, &for_previews_xform, 64);
Vector<int> items = ml->get_item_list();
assert(items.size() == previews.size());
for (i = 0; i < items.size(); i++) {
int id = items[i];
ml->set_item_preview(id, previews[i]);
}
ResourceSaver::save("res://astream/buildings.meshlib", ml);
}
static ElementTypeEditor *etype_editor; static ElementTypeEditor *etype_editor;
static ElementEditor *element_editor; static ElementEditor *element_editor;
static LayoutEditor *layout_editor; static LayoutEditor *layout_editor;
@@ -1361,6 +1494,10 @@ void BuildingLayoutEditor::menu_control(int id)
switch (id) { switch (id) {
case 100: case 100:
save_data(); save_data();
update_layout_meshes();
break;
case 101:
update_layout_meshes();
break; break;
case 200: // layout mode case 200: // layout mode
get_as_node<Control>("%socket_editor")->hide(); get_as_node<Control>("%socket_editor")->hide();

View File

@@ -13,6 +13,7 @@ class BuildingLayoutEditor : public Node {
Ref<Texture> preview; Ref<Texture> preview;
}; };
HashMap<String, struct mesh_data> meshes; HashMap<String, struct mesh_data> meshes;
HashMap<String, Ref<Mesh> > layout_meshes;
bool meshes_ready; bool meshes_ready;
int current_mode; int current_mode;
@@ -27,10 +28,12 @@ public:
Ref<Texture> get_mesh_preview(const String &key); Ref<Texture> get_mesh_preview(const String &key);
void visualize_element_type(const String &key, void visualize_element_type(const String &key,
const String &test_element); const String &test_element);
void visualize_element_at(const String &element, Spatial *node); void visualize_element_at(const String &element, Spatial *node) const;
Ref<Mesh> get_element_mesh(const String &element) const; Ref<Mesh> get_element_mesh(const String &element) const;
Ref<Mesh> get_layout_exterior_mesh(const String &layout) const;
void update_element_meshes(); void update_element_meshes();
void update_layout_meshes();
protected: protected:
void _notification(int which); void _notification(int which);

View File

@@ -358,7 +358,7 @@ void ElementData::unserialize_layouts(const Dictionary &store)
ecs.entity(floor_key.ascii().ptr()) ecs.entity(floor_key.ascii().ptr())
.child_of(intr); .child_of(intr);
assert(floor_e.is_valid()); assert(floor_e.is_valid());
floor_e.add<struct grid_floor>(); floor_e.set<struct grid_floor>({ true });
const Array &floor_interior = const Array &floor_interior =
store_interior[floor_key]; store_interior[floor_key];
for (i = 0; i < floor_interior.size(); i++) { for (i = 0; i < floor_interior.size(); i++) {

View File

@@ -98,7 +98,9 @@ public:
}; };
struct grid_layout_exterior {}; struct grid_layout_exterior {};
struct grid_layout_interior {}; struct grid_layout_interior {};
struct grid_floor {}; struct grid_floor {
bool dirty;
};
struct grid_floor_item { struct grid_floor_item {
int index; int index;
String element; String element;
@@ -139,6 +141,13 @@ protected:
s.node->queue_delete(); s.node->queue_delete();
s.node = nullptr; s.node = nullptr;
}); });
ecs.observer<struct grid_floor_item_node>()
.event(flecs::OnSet)
.each([](flecs::entity em,
struct grid_floor_item_node &s) {
em.parent().get_mut<struct grid_floor>()->dirty =
true;
});
} }
HashMap<String, struct grid_element_type> element_type; HashMap<String, struct grid_element_type> element_type;
HashMap<String, struct grid_element> elements; HashMap<String, struct grid_element> elements;
@@ -159,11 +168,16 @@ public:
{ {
return grid_size; return grid_size;
} }
inline flecs::entity get_base(const String &key, bool exterior) const inline const flecs::entity get_layout(const String &key) 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());
return layout;
}
inline flecs::entity get_base(const String &key, bool exterior) const
{
flecs::entity layout = get_layout(key);
assert(layout.is_valid()); assert(layout.is_valid());
flecs::entity base; flecs::entity base;
if (exterior) if (exterior)