Compare commits
3 Commits
b6b5fdada9
...
997b66b7f9
| Author | SHA1 | Date | |
|---|---|---|---|
| 997b66b7f9 | |||
| b2fe7d7e46 | |||
| 844056de64 |
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -9,3 +9,7 @@
|
||||
[submodule "src/flecs"]
|
||||
path = src/flecs
|
||||
url = https://github.com/SanderMertens/flecs
|
||||
[submodule "src/meshoptimizer"]
|
||||
path = src/meshoptimizer
|
||||
url = https://github.com/zeux/meshoptimizer
|
||||
branch = master
|
||||
|
||||
Binary file not shown.
@@ -118,6 +118,21 @@ elements={
|
||||
"mesh_names": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ],
|
||||
"name": "test_element",
|
||||
"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={
|
||||
@@ -2832,7 +2847,7 @@ grid_layouts={
|
||||
"index": 26,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 27,
|
||||
"rotation": 3
|
||||
}, {
|
||||
@@ -2860,7 +2875,7 @@ grid_layouts={
|
||||
"index": 33,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 34,
|
||||
"rotation": 1
|
||||
}, {
|
||||
@@ -2868,7 +2883,7 @@ grid_layouts={
|
||||
"index": 35,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 36,
|
||||
"rotation": 3
|
||||
}, {
|
||||
@@ -2896,7 +2911,7 @@ grid_layouts={
|
||||
"index": 42,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 43,
|
||||
"rotation": 1
|
||||
}, {
|
||||
@@ -2904,7 +2919,7 @@ grid_layouts={
|
||||
"index": 44,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 45,
|
||||
"rotation": 3
|
||||
}, {
|
||||
@@ -2932,7 +2947,7 @@ grid_layouts={
|
||||
"index": 51,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 52,
|
||||
"rotation": 1
|
||||
}, {
|
||||
@@ -2940,7 +2955,7 @@ grid_layouts={
|
||||
"index": 53,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 54,
|
||||
"rotation": 3
|
||||
}, {
|
||||
@@ -2968,7 +2983,7 @@ grid_layouts={
|
||||
"index": 60,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 61,
|
||||
"rotation": 1
|
||||
}, {
|
||||
@@ -2976,7 +2991,7 @@ grid_layouts={
|
||||
"index": 62,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 63,
|
||||
"rotation": 3
|
||||
}, {
|
||||
@@ -3004,7 +3019,7 @@ grid_layouts={
|
||||
"index": 69,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "side_wall",
|
||||
"element": "side_wall_no_floor",
|
||||
"index": 70,
|
||||
"rotation": 1
|
||||
}, {
|
||||
@@ -3157,7 +3172,7 @@ grid_layouts={
|
||||
"index": 26,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "roof_corner2",
|
||||
"element": "roof_mid_corner2",
|
||||
"index": 27,
|
||||
"rotation": 2
|
||||
}, {
|
||||
@@ -3879,35 +3894,35 @@ grid_layouts={
|
||||
"index": 44,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile_side",
|
||||
"index": 45,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 46,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 47,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 48,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 49,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 50,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile",
|
||||
"index": 51,
|
||||
"rotation": 0
|
||||
}, {
|
||||
"element": "empty",
|
||||
"element": "top_single_tile_side2",
|
||||
"index": 52,
|
||||
"rotation": 0
|
||||
}, {
|
||||
|
||||
Binary file not shown.
BIN
godot/astream/buildings.meshlib
Normal file
BIN
godot/astream/buildings.meshlib
Normal file
Binary file not shown.
39
godot/main/test.tscn
Normal file
39
godot/main/test.tscn
Normal file
File diff suppressed because one or more lines are too long
Submodule src/godot updated: 019ca01ddc...3ee8ecdf25
1
src/meshoptimizer
Submodule
1
src/meshoptimizer
Submodule
Submodule src/meshoptimizer added at 7f936ad1b5
@@ -12,6 +12,7 @@ module_obj = []
|
||||
|
||||
SConscript("buildings/SCsub")
|
||||
|
||||
env_stream.Prepend(CPPPATH=["../../meshoptimizer/src"])
|
||||
env_stream.add_source_files(module_obj, "*.cpp")
|
||||
env_stream.add_source_files(module_obj, "flecs/*.c")
|
||||
env.modules_sources += module_obj
|
||||
|
||||
@@ -15,3 +15,4 @@ env.add_source_files(env.stream_building_sources, "*.cpp")
|
||||
lib = env.add_library("buildings", env.stream_building_sources)
|
||||
env.Prepend(LIBS=[lib])
|
||||
env.Prepend(CPPPATH=[".."])
|
||||
env.Prepend(CPPPATH=["../../../meshoptimizer/src"])
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <core/os/input.h>
|
||||
#include <scene/resources/packed_scene.h>
|
||||
#include <scene/resources/surface_tool.h>
|
||||
#include <scene/resources/mesh_library.h>
|
||||
#include <scene/3d/mesh_instance.h>
|
||||
#include <scene/main/viewport.h>
|
||||
#include <scene/3d/camera.h>
|
||||
@@ -17,6 +18,12 @@
|
||||
#include <scene/gui/menu_button.h>
|
||||
#include <editor/editor_node.h>
|
||||
#include <flecs/flecs.h>
|
||||
namespace meshoptimizer
|
||||
{
|
||||
#define MESHOPTIMIZER_API static
|
||||
#include <meshoptimizer.h>
|
||||
#include <simplifier.cpp>
|
||||
}
|
||||
#include "editor_event.h"
|
||||
#include "element_data.h"
|
||||
#include "building_layout_editor.h"
|
||||
@@ -1078,9 +1085,8 @@ void BuildingLayoutEditor::visualize_element_type(const String &key,
|
||||
}
|
||||
|
||||
void BuildingLayoutEditor::visualize_element_at(const String &element,
|
||||
Spatial *node)
|
||||
Spatial *node) const
|
||||
{
|
||||
int i;
|
||||
if (!ElementData::get_singleton()->has_element(element))
|
||||
return;
|
||||
const String &element_type =
|
||||
@@ -1148,6 +1154,252 @@ Ref<Mesh> BuildingLayoutEditor::get_element_mesh(const String &element) const
|
||||
assert(ret.is_valid());
|
||||
return ret;
|
||||
}
|
||||
Ref<Mesh> BuildingLayoutEditor::get_layout_exterior_mesh(const String &layout,
|
||||
int lod) 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();
|
||||
print_line("optimizing for lod: " + itos(lod));
|
||||
if (lod > 0) {
|
||||
const PoolVector<Vector2> &uvs = arr[Mesh::ARRAY_TEX_UV];
|
||||
const PoolVector<int> &index_array = arr[Mesh::ARRAY_INDEX];
|
||||
LocalVector<Color> colors;
|
||||
colors.resize(uvs.size());
|
||||
{
|
||||
Ref<SpatialMaterial> spmat = mat;
|
||||
assert(spmat.is_valid());
|
||||
Ref<Texture> albedo_texture = spmat->get_texture(
|
||||
SpatialMaterial::TEXTURE_ALBEDO);
|
||||
assert(albedo_texture.is_valid());
|
||||
Ref<Image> img_data = albedo_texture->get_data();
|
||||
assert(img_data.is_valid());
|
||||
img_data->lock();
|
||||
for (i = 0; i < uvs.size(); i++)
|
||||
colors[i] = img_data->get_pixelv(
|
||||
uvs[i] * img_data->get_size());
|
||||
img_data->unlock();
|
||||
}
|
||||
HashMap<Color, int> map_colors;
|
||||
HashMap<int, int[3]> base_uvs;
|
||||
Set<Color> seen_colors;
|
||||
for (i = 0; i < colors.size(); i++) {
|
||||
int j;
|
||||
Color base = colors[i];
|
||||
if (seen_colors.has(base))
|
||||
continue;
|
||||
map_colors[base] = i;
|
||||
base_uvs[i][0] = i;
|
||||
for (j = 0; j < colors.size(); j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
if (base.is_equal_approx(colors[j])) {
|
||||
const Vector2 &w = uvs[base_uvs[i][0]];
|
||||
if (w.x > uvs[j].x && w.y > uvs[j].y)
|
||||
base_uvs[i][0] = j;
|
||||
}
|
||||
}
|
||||
base_uvs[i][1] = i;
|
||||
for (j = 0; j < colors.size(); j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
if (base.is_equal_approx(colors[j])) {
|
||||
const Vector2 &w = uvs[base_uvs[i][1]];
|
||||
if (w.x < uvs[j].x && w.y > uvs[j].y)
|
||||
base_uvs[i][1] = j;
|
||||
}
|
||||
}
|
||||
base_uvs[i][2] = i;
|
||||
for (j = 0; j < colors.size(); j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
if (base.is_equal_approx(colors[j])) {
|
||||
const Vector2 &w = uvs[base_uvs[i][2]];
|
||||
if (w.x < uvs[j].x && w.y < uvs[j].y)
|
||||
base_uvs[i][2] = j;
|
||||
}
|
||||
}
|
||||
seen_colors.insert(base);
|
||||
}
|
||||
List<int> keys;
|
||||
base_uvs.get_key_list(&keys);
|
||||
List<int>::Element *e = keys.front();
|
||||
while (e) {
|
||||
print_line(
|
||||
"color: " +
|
||||
(colors[e->get()].operator String()) + " " +
|
||||
(uvs[base_uvs[e->get()][0]].operator String()) +
|
||||
" " +
|
||||
(uvs[base_uvs[e->get()][1]].operator String()) +
|
||||
" " +
|
||||
(uvs[base_uvs[e->get()][2]].operator String()));
|
||||
e = e->next();
|
||||
}
|
||||
PoolVector<Vector2> uv_remap;
|
||||
uv_remap.resize(uvs.size());
|
||||
for (i = 0; i < index_array.size(); i++) {
|
||||
int idx = index_array[i];
|
||||
int state = i % 3;
|
||||
int c = map_colors[colors[idx]];
|
||||
int uv_idx = base_uvs[c][state];
|
||||
uv_remap.write()[idx] = uvs[uv_idx];
|
||||
}
|
||||
arr[Mesh::ARRAY_TEX_UV] = uv_remap;
|
||||
PoolVector<int> lodv;
|
||||
LocalVector<float> vertices;
|
||||
const PoolVector<Vector3> &vertex_array =
|
||||
arr[Mesh::ARRAY_VERTEX];
|
||||
lodv.resize(index_array.size());
|
||||
vertices.resize(vertex_array.size() * 3);
|
||||
for (i = 0; i < vertex_array.size(); i++) {
|
||||
vertices[i * 3 + 0] = vertex_array[i].x;
|
||||
vertices[i * 3 + 1] = vertex_array[i].y;
|
||||
vertices[i * 3 + 2] = vertex_array[i].z;
|
||||
}
|
||||
float error = 0.f;
|
||||
const int simplify_options = 1; /* lock border */
|
||||
float threshold = 1.0f;
|
||||
float target_error = 0.01f;
|
||||
bool sloppy = false;
|
||||
switch (lod) {
|
||||
case 1:
|
||||
threshold = 0.6f;
|
||||
target_error = 0.01f;
|
||||
sloppy = false;
|
||||
break;
|
||||
case 2:
|
||||
threshold = 0.3f;
|
||||
target_error = 0.01f;
|
||||
sloppy = false;
|
||||
break;
|
||||
default:
|
||||
threshold = 1.0f / (float(lod + 1));
|
||||
target_error = 0.01;
|
||||
sloppy = true;
|
||||
break;
|
||||
}
|
||||
int target_index_count = index_array.size() * threshold;
|
||||
print_line("meshopt for lod: " + itos(lod));
|
||||
print_line("output size: " + itos(lodv.size()));
|
||||
print_line("index size: " + itos(index_array.size()));
|
||||
print_line("vertex count: " + itos(vertex_array.size()));
|
||||
print_line("vertex buffer size: " + itos(vertices.size()));
|
||||
int index_count = 0;
|
||||
if (!sloppy)
|
||||
index_count = meshoptimizer::meshopt_simplify(
|
||||
(unsigned int *)lodv.write().ptr(),
|
||||
(const unsigned int *)index_array.read().ptr(),
|
||||
(size_t)index_array.size(), vertices.ptr(),
|
||||
(size_t)vertex_array.size(),
|
||||
(size_t)(sizeof(float) * 3),
|
||||
(size_t)target_index_count, target_error,
|
||||
simplify_options, &error);
|
||||
else
|
||||
index_count = meshoptimizer::meshopt_simplifySloppy(
|
||||
(unsigned int *)lodv.write().ptr(),
|
||||
(const unsigned int *)index_array.read().ptr(),
|
||||
(size_t)index_array.size(), vertices.ptr(),
|
||||
(size_t)vertex_array.size(),
|
||||
(size_t)(sizeof(float) * 3),
|
||||
(size_t)target_index_count, target_error,
|
||||
&error);
|
||||
assert(index_count > 0);
|
||||
lodv.resize(index_count);
|
||||
#if 0
|
||||
meshopt_optimizeVertexCache(lodv.write().ptr(),
|
||||
lodv.read().ptr(), index_count,
|
||||
vertex_array.size());
|
||||
meshopt_optimizeOverdraw(lodv.write().ptr(), lodv.read().ptr(),
|
||||
index_count, vertices.ptr(),
|
||||
vertex_array.size(),
|
||||
(size_t)(sizeof(float) * 3), 1.05f);
|
||||
#endif
|
||||
arr[Mesh::ARRAY_INDEX] = lodv;
|
||||
print_line("final output size: " + itos(lodv.size()));
|
||||
}
|
||||
print_line("optimizing for lod: " + itos(lod) + " done");
|
||||
|
||||
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()
|
||||
{
|
||||
List<String> keys;
|
||||
@@ -1164,6 +1416,55 @@ 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());
|
||||
for (lod = 0; lod < 4; lod++) {
|
||||
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(), lod);
|
||||
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 ElementEditor *element_editor;
|
||||
static LayoutEditor *layout_editor;
|
||||
@@ -1361,6 +1662,10 @@ void BuildingLayoutEditor::menu_control(int id)
|
||||
switch (id) {
|
||||
case 100:
|
||||
save_data();
|
||||
update_layout_meshes();
|
||||
break;
|
||||
case 101:
|
||||
update_layout_meshes();
|
||||
break;
|
||||
case 200: // layout mode
|
||||
get_as_node<Control>("%socket_editor")->hide();
|
||||
|
||||
@@ -13,6 +13,7 @@ class BuildingLayoutEditor : public Node {
|
||||
Ref<Texture> preview;
|
||||
};
|
||||
HashMap<String, struct mesh_data> meshes;
|
||||
HashMap<String, Ref<Mesh> > layout_meshes;
|
||||
bool meshes_ready;
|
||||
int current_mode;
|
||||
|
||||
@@ -27,10 +28,12 @@ public:
|
||||
Ref<Texture> get_mesh_preview(const String &key);
|
||||
void visualize_element_type(const String &key,
|
||||
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_layout_exterior_mesh(const String &layout, int lod) const;
|
||||
|
||||
void update_element_meshes();
|
||||
void update_layout_meshes();
|
||||
|
||||
protected:
|
||||
void _notification(int which);
|
||||
|
||||
@@ -358,7 +358,7 @@ void ElementData::unserialize_layouts(const Dictionary &store)
|
||||
ecs.entity(floor_key.ascii().ptr())
|
||||
.child_of(intr);
|
||||
assert(floor_e.is_valid());
|
||||
floor_e.add<struct grid_floor>();
|
||||
floor_e.set<struct grid_floor>({ true });
|
||||
const Array &floor_interior =
|
||||
store_interior[floor_key];
|
||||
for (i = 0; i < floor_interior.size(); i++) {
|
||||
|
||||
@@ -98,7 +98,9 @@ public:
|
||||
};
|
||||
struct grid_layout_exterior {};
|
||||
struct grid_layout_interior {};
|
||||
struct grid_floor {};
|
||||
struct grid_floor {
|
||||
bool dirty;
|
||||
};
|
||||
struct grid_floor_item {
|
||||
int index;
|
||||
String element;
|
||||
@@ -139,6 +141,13 @@ protected:
|
||||
s.node->queue_delete();
|
||||
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> elements;
|
||||
@@ -159,11 +168,16 @@ public:
|
||||
{
|
||||
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");
|
||||
assert(top.is_valid());
|
||||
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());
|
||||
flecs::entity base;
|
||||
if (exterior)
|
||||
|
||||
Reference in New Issue
Block a user