Completed conversion of buildings handling to ECS systems
This commit is contained in:
9
Makefile
9
Makefile
@@ -5,12 +5,14 @@ EDITOR_PLATFORM=x11es
|
||||
EDITOR2_PLATFORM=x11
|
||||
DEMO_PLATFORMS=x11 x11es
|
||||
EDITOR = src/godot/bin/godot.$(EDITOR_PLATFORM).opt.tools.$(ARCH)
|
||||
EDITOR_DBG = src/godot/bin/godot.$(EDITOR_PLATFORM).tools.$(ARCH)
|
||||
EDITOR2 = src/godot/bin/godot.$(EDITOR2_PLATFORM).opt.tools.$(ARCH)
|
||||
EDITOR2_DBG = src/godot/bin/godot.$(EDITOR2_PLATFORM).tools.$(ARCH)
|
||||
|
||||
.PHONY: all godot-editor-main export export-models export-clothes \
|
||||
.PHONY: all godot-editor-main godot-editor-debug export export-models export-clothes \
|
||||
export-clean export-linux-demo export-windows-demo \
|
||||
export-binaries patch tests import-vrm export-buildings
|
||||
all: godot-editor-main godot-main
|
||||
all: godot-editor-main godot-editor-debug godot-main
|
||||
SCONS_EXTRA=-j16
|
||||
define build_godot
|
||||
$(4): $(5)
|
||||
@@ -31,12 +33,15 @@ $(foreach pt,$(DEMO_PLATFORMS),$(eval $(call build_godot_platform,$(pt))))
|
||||
godot-main: $(GODOT_MAIN_TARGETS) godot-editor-main godot-server-main
|
||||
godot-server-main: $(SERVER)
|
||||
godot-editor-main: $(EDITOR) $(EDITOR2)
|
||||
godot-editor-debug: $(EDITOR_DBG) $(EDITOR2_DBG)
|
||||
#$(SERVER): patch
|
||||
# cd src/godot; \
|
||||
# scons platform=server arch=$(ARCH) target=release_debug tools=yes custom_modules=../modules -j16
|
||||
$(eval $(call build_godot,server,release_debug,yes,$(SERVER),patch))
|
||||
$(eval $(call build_godot,x11es,release_debug,yes,$(EDITOR),patch))
|
||||
$(eval $(call build_godot,x11es,debug,yes,$(EDITOR_DBG),patch))
|
||||
$(eval $(call build_godot,x11,release_debug,yes,$(EDITOR2),patch))
|
||||
$(eval $(call build_godot,x11,debug,yes,$(EDITOR2_DBG),patch))
|
||||
patch: ./src/godot/scene/animation/skeleton_ik.cpp
|
||||
cd ./src/godot && git reset --hard HEAD && rm -Rf platform/x11es && for p in ../patches/*.patch; do git apply $$p; done
|
||||
sed -e 's/ERR_FAIL_COND_V(-1 == p_task->root_bone, false);//g' -i ./src/godot/scene/animation/skeleton_ik.cpp
|
||||
|
||||
Submodule src/flecs updated: fa9bfa08d7...99c822674a
Submodule src/godot updated: 9fccb6b2d7...bec38d9248
Submodule src/meshoptimizer updated: 515e92fb70...57123951b5
@@ -15,13 +15,7 @@
|
||||
#include "base_data.h"
|
||||
#include "buildings_data.h"
|
||||
|
||||
static ConfigFile config;
|
||||
static ConfigFile custom_layouts;
|
||||
struct scene_data {
|
||||
Ref<PackedScene> packed_scene;
|
||||
String path;
|
||||
Ref<ResourceInteractiveLoader> loader;
|
||||
};
|
||||
ConfigFile BuildingsData::config;
|
||||
|
||||
static flecs::world &ecs()
|
||||
{
|
||||
@@ -37,250 +31,12 @@ static flecs::entity lookup(const char *key)
|
||||
{
|
||||
return ecs().lookup(key);
|
||||
}
|
||||
|
||||
struct CBuildingInstance {
|
||||
String key;
|
||||
Node *node;
|
||||
};
|
||||
|
||||
struct CSceneData {
|
||||
struct scene_data sd;
|
||||
};
|
||||
|
||||
#if 0
|
||||
void BuildingsData::load_tile(std::tuple<int, int> key)
|
||||
{
|
||||
int i;
|
||||
const std::vector<String> &items = tiles[key];
|
||||
for (i = 0; i < (int)items.size(); i++) {
|
||||
print_verbose("load item: " + itos(i) + ": key: " + (items[i]) +
|
||||
": " /* + data()->get_building(items[i]).id */);
|
||||
const String &bkey = items[i];
|
||||
flecs::entity eb = get_building_entity(bkey);
|
||||
if (eb.is_valid()) {
|
||||
if (!eb.has<BuildingsData::CBuildingLoaded>())
|
||||
eb.add<BuildingsData::CBuildingLoad>();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BuildingsData::BuildingsData()
|
||||
: undo_log_size(64)
|
||||
{
|
||||
flecs::world ecs_ = ecs();
|
||||
ecs_.component<CBuildingStats>();
|
||||
ecs_.component<CBuildingData>();
|
||||
ecs_.component<CBTypeResidental>();
|
||||
ecs_.component<CBCustomLayout>();
|
||||
ecs_.component<CBuildingEdited>();
|
||||
ecs_.component<CBuildingTileData>();
|
||||
ecs_.component<CBuildingsEye>();
|
||||
bool deferred = ecs_.is_deferred();
|
||||
if (deferred)
|
||||
ecs_.defer_suspend();
|
||||
ecs_.set<CBuildingStats>({ 0 });
|
||||
ecs_.set<CBuildingTileData>({});
|
||||
assert(ecs_.has<CBuildingStats>());
|
||||
load_data();
|
||||
ecs_.query_builder<const CBuildingData>().build().each(
|
||||
[](flecs::entity e, const CBuildingData &bd) {
|
||||
print_line("created: " + bd.building.key + " / " +
|
||||
String(e.name()));
|
||||
});
|
||||
if (deferred)
|
||||
ecs_.defer_resume();
|
||||
print_line("loaded buildings: " +
|
||||
itos(ecs().get<CBuildingStats>()->created_entities));
|
||||
assert(ecs().get<CBuildingStats>()->created_entities > 0);
|
||||
fill_door_locations();
|
||||
build_building_aabbs();
|
||||
ecs_.observer<CBuildingInstance>()
|
||||
.event(flecs::OnRemove)
|
||||
.each([](flecs::entity e, CBuildingInstance &bi) {
|
||||
if (bi.node) {
|
||||
bi.node->queue_delete();
|
||||
bi.node = nullptr;
|
||||
// print_line("instance destroyed for " + bi.key);
|
||||
}
|
||||
});
|
||||
ecs_.observer<CBuildingEdited>()
|
||||
.event(flecs::OnAdd)
|
||||
.with<CBuildingData>()
|
||||
.run([&](flecs::iter &it) {
|
||||
flecs::query<const CBuildingData> q =
|
||||
it.world()
|
||||
.query_builder<const CBuildingData>()
|
||||
.with<CBuildingEdited>()
|
||||
.build();
|
||||
if (it.next()) {
|
||||
flecs::entity qe = it.entity(0);
|
||||
q.each([qe](flecs::entity e,
|
||||
const CBuildingData &d) {
|
||||
if (e != qe)
|
||||
e.remove<CBuildingEdited>();
|
||||
});
|
||||
print_line("Selected building " +
|
||||
String(qe.name()));
|
||||
// it.fini();
|
||||
}
|
||||
});
|
||||
ecs_.system("UpdateEye").kind(flecs::OnUpdate).run([&](flecs::iter &it) {
|
||||
Viewport *viewport = SceneTree::get_singleton()
|
||||
->get_current_scene()
|
||||
->get_viewport();
|
||||
int i, j, l;
|
||||
int tile_size = config.get_value("world", "tile_size");
|
||||
int view_distance = config.get_value("world", "view_distance");
|
||||
assert(tile_size > 0);
|
||||
Transform xform =
|
||||
viewport->get_camera()->get_global_transform();
|
||||
Vector3 eye = xform.origin;
|
||||
int tile_x = int(eye.x / tile_size);
|
||||
int tile_z = int(eye.z / tile_size);
|
||||
bool need_update = true;
|
||||
if (it.world().has<CBuildingsEye>()) {
|
||||
int old_x = it.world().get<CBuildingsEye>()->tile_x;
|
||||
int old_z = it.world().get<CBuildingsEye>()->tile_z;
|
||||
if (old_x == tile_x && old_z == tile_z)
|
||||
need_update = false;
|
||||
}
|
||||
it.world().set<CBuildingsEye>({ xform, tile_x, tile_z });
|
||||
if (need_update)
|
||||
return;
|
||||
if (!it.world().has<CBuildingTileData>())
|
||||
return;
|
||||
CBuildingTileData *td = it.world().get_mut<CBuildingTileData>();
|
||||
it.world()
|
||||
.query_builder<CBuildingData>()
|
||||
.without<CBuildingLoaded>()
|
||||
.without<CBuildingLoad>()
|
||||
.with<CBuildingTile>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
const CBuildingTile *bt =
|
||||
e.get<CBuildingTile>();
|
||||
std::tuple<int, int> tile = bt->tile;
|
||||
int t_x = std::get<0>(tile);
|
||||
int t_z = std::get<1>(tile);
|
||||
if (t_x > tile_x - view_distance &&
|
||||
t_x < tile_x + view_distance &&
|
||||
t_z > tile_z - view_distance &&
|
||||
t_z < tile_z + view_distance) {
|
||||
if (e.is_valid()) {
|
||||
e.add<BuildingsData::
|
||||
CBuildingLoad>();
|
||||
}
|
||||
}
|
||||
});
|
||||
it.world()
|
||||
.query_builder<CBuildingData>()
|
||||
.with<CBuildingLoaded>()
|
||||
.with<CBuildingTile>()
|
||||
.without<CBuildingUnload>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
const CBuildingTile *bt =
|
||||
e.get<CBuildingTile>();
|
||||
std::tuple<int, int> tile = bt->tile;
|
||||
int erase_distance = view_distance + 1;
|
||||
int ed2 = erase_distance * erase_distance;
|
||||
|
||||
int t_x = std::get<0>(tile);
|
||||
int t_z = std::get<1>(tile);
|
||||
int d1 = t_x - tile_x;
|
||||
int d2 = t_z - tile_z;
|
||||
if (d1 * d1 > ed2 || d2 * d2 > ed2)
|
||||
if (e.is_valid()) {
|
||||
e.add<BuildingsData::
|
||||
CBuildingUnload>();
|
||||
}
|
||||
});
|
||||
});
|
||||
ecs_.system<const CBuildingData>("LoadData")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<CBuildingLoaded>()
|
||||
.with<CBuildingLoad>()
|
||||
.write<CBuildingLoaded>()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
e.world().defer_suspend();
|
||||
bool debug = false;
|
||||
// if (bd.building.key.begins_with("road__"))
|
||||
// debug = true;
|
||||
String id = bd.building.id;
|
||||
if (debug)
|
||||
print_verbose("add to scene id: " + id);
|
||||
if (!has_scene(id))
|
||||
create_scene_data(id, bd.building.key);
|
||||
else
|
||||
add_scene_item(id, bd.building.key);
|
||||
if (debug)
|
||||
print_verbose("added to scene id: " + id);
|
||||
e.add<CBuildingLoaded>();
|
||||
e.remove<CBuildingLoad>();
|
||||
e.world().defer_resume();
|
||||
});
|
||||
ecs_.system<const CBuildingData>("UnloadData")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<CBuildingUnload>()
|
||||
.with<CBuildingLoaded>()
|
||||
.write<CBuildingLoaded>()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
bool debug = false;
|
||||
// if (bd.building.key.begins_with("road__"))
|
||||
// debug = true;
|
||||
String id = bd.building.key;
|
||||
if (debug)
|
||||
print_verbose("removed from scene id: " + id);
|
||||
if (has_scene(id))
|
||||
remove_scene_item(id, bd.building.key);
|
||||
e.remove<CBuildingLoaded>();
|
||||
e.remove<CBuildingUnload>();
|
||||
});
|
||||
}
|
||||
|
||||
BuildingsData::~BuildingsData()
|
||||
{
|
||||
}
|
||||
|
||||
void BuildingsData::build_building_aabbs()
|
||||
{
|
||||
building_aabbs.clear();
|
||||
List<String> keys;
|
||||
building_data.get_key_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
Error err;
|
||||
const String &path = building_data[e->get()];
|
||||
Ref<PackedScene> ps =
|
||||
ResourceLoader::load(path, "PackedScene", true, &err);
|
||||
if (err == OK && ps.is_valid()) {
|
||||
AABB aabb;
|
||||
Node *scene = ps->instance();
|
||||
List<Node *> queue;
|
||||
queue.push_back(scene);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
Node *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
MeshInstance *mi =
|
||||
Object::cast_to<MeshInstance>(item);
|
||||
if (mi) {
|
||||
if (aabb.size.length_squared() < 0.1f)
|
||||
aabb = mi->get_aabb();
|
||||
else
|
||||
aabb.merge_with(mi->get_aabb());
|
||||
}
|
||||
for (i = 0; i < item->get_child_count(); i++)
|
||||
queue.push_back(item->get_child(i));
|
||||
}
|
||||
building_aabbs[e->get()] = aabb;
|
||||
scene->queue_delete();
|
||||
ps.unref();
|
||||
} else
|
||||
print_error("Could not load: " + path);
|
||||
e = e->next();
|
||||
}
|
||||
// building_aabbs.clear();
|
||||
// List<String> keys;
|
||||
// building_data.get_key_list(&keys);
|
||||
// List<String>::Element *e = keys.front();
|
||||
}
|
||||
|
||||
void BuildingsData::update_building_transform(const String &key,
|
||||
@@ -301,7 +57,7 @@ bool BuildingsData::has_building(const String &key)
|
||||
return e.is_valid();
|
||||
}
|
||||
|
||||
String BuildingsData::get_closest_building(const Transform &xform) const
|
||||
String BuildingsData::get_closest_building(const Transform &xform)
|
||||
{
|
||||
float dst = Math_INF;
|
||||
String rkey;
|
||||
@@ -318,8 +74,7 @@ String BuildingsData::get_closest_building(const Transform &xform) const
|
||||
});
|
||||
return rkey;
|
||||
}
|
||||
flecs::entity
|
||||
BuildingsData::get_closest_building_entity(const Transform &xform) const
|
||||
flecs::entity BuildingsData::get_closest_building_entity(const Transform &xform)
|
||||
{
|
||||
float dst = Math_INF;
|
||||
String rkey;
|
||||
@@ -500,6 +255,7 @@ void BuildingsData::load_data()
|
||||
assert(ecs().has<CBuildingStats>());
|
||||
Error result = config.load("res://config/stream.conf");
|
||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||
#if 0
|
||||
Dictionary buildings_data =
|
||||
config.get_value("buildings", "building_data");
|
||||
List<Variant> keys;
|
||||
@@ -507,7 +263,23 @@ void BuildingsData::load_data()
|
||||
List<Variant>::Element *e = keys.front();
|
||||
while (e) {
|
||||
String key = e->get();
|
||||
building_data[key] = buildings_data[key];
|
||||
// building_data[key] = buildings_data[key];
|
||||
flecs::entity se = ecs().entity(key.ascii().ptr());
|
||||
// print_line("scene key: " + key);
|
||||
assert(buildings_data.has(key));
|
||||
String path = buildings_data[key];
|
||||
// print_line("path: " + path);
|
||||
assert(path.length() > 5);
|
||||
// print_line("Requesting " + (bkey) + " " + path);
|
||||
assert(!pending_scene.has(path));
|
||||
struct scene_data sd;
|
||||
sd.path = path;
|
||||
sd.loader = ResourceLoader::load_interactive(
|
||||
path, "PackedScene", true);
|
||||
assert(sd.loader.is_valid());
|
||||
se.set<CSceneData>({ sd });
|
||||
pending_scene.insert(path);
|
||||
assert(se.get_mut<CSceneData>());
|
||||
e = e->next();
|
||||
}
|
||||
e = keys.front();
|
||||
@@ -516,12 +288,14 @@ void BuildingsData::load_data()
|
||||
// print_line(key + ": " + buildings_data[key]);
|
||||
e = e->next();
|
||||
}
|
||||
#endif
|
||||
String buildings_path = config.get_value("buildings", "buildings_path");
|
||||
read_buildings_json(buildings_path);
|
||||
}
|
||||
|
||||
void BuildingsData::checkpoint()
|
||||
{
|
||||
#if 0
|
||||
struct checkpoint_data cp;
|
||||
cp.building_data = building_data;
|
||||
cp.buildings.clear();
|
||||
@@ -531,9 +305,11 @@ void BuildingsData::checkpoint()
|
||||
undo_log.push_back(cp);
|
||||
while ((int)undo_log.size() > undo_log_size)
|
||||
undo_log.erase(undo_log.begin());
|
||||
#endif
|
||||
}
|
||||
void BuildingsData::undo()
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
struct checkpoint_data cp = *undo_log.end();
|
||||
building_data = cp.building_data;
|
||||
@@ -545,98 +321,44 @@ void BuildingsData::undo()
|
||||
flecs::entity e = ecs().entity(ename.ascii().ptr());
|
||||
e.set<CBuildingData>({ cp.buildings[i] });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BuildingsData::fill_door_locations()
|
||||
{
|
||||
/*
|
||||
func fill_door_locations():
|
||||
for k in building_data.keys():
|
||||
var bdoors = []
|
||||
var l = building_data[k].instance()
|
||||
var queue = [l]
|
||||
while queue.size() > 0:
|
||||
var item = queue.pop_front()
|
||||
if item.name.find("-portal") >= 0:
|
||||
var xform = item.transform
|
||||
var tmp = item.get_parent()
|
||||
while tmp != null:
|
||||
var parent_xform = tmp.transform
|
||||
xform = parent_xform * xform
|
||||
tmp = tmp.get_parent()
|
||||
bdoors.push_back(var2str(xform))
|
||||
for c in item.get_children():
|
||||
queue.push_back(c)
|
||||
door_locations[k] = bdoors
|
||||
l.queue_free()
|
||||
*/
|
||||
List<String> keys;
|
||||
building_data.get_key_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
Error err;
|
||||
const String &path = building_data[e->get()];
|
||||
Ref<PackedScene> ps =
|
||||
ResourceLoader::load(path, "PackedScene", true, &err);
|
||||
if (err == OK && ps.is_valid()) {
|
||||
Vector<Transform> doors;
|
||||
Node *scene = ps->instance();
|
||||
List<Node *> queue;
|
||||
queue.push_back(scene);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
Node *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
String name = item->get_name();
|
||||
if (name.find("-portal") >= 0) {
|
||||
Spatial *sp =
|
||||
Object::cast_to<Spatial>(item);
|
||||
if (sp) {
|
||||
Transform xform =
|
||||
sp->get_transform();
|
||||
Node *tmp = item->get_parent();
|
||||
while (tmp) {
|
||||
Transform parent_xform;
|
||||
Spatial *parent_sp =
|
||||
Object::cast_to<
|
||||
Spatial>(
|
||||
tmp);
|
||||
if (parent_sp)
|
||||
parent_xform =
|
||||
parent_sp
|
||||
->get_transform();
|
||||
xform = parent_xform *
|
||||
xform;
|
||||
tmp = tmp->get_parent();
|
||||
}
|
||||
doors.push_back(xform);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < item->get_child_count(); i++)
|
||||
queue.push_back(item->get_child(i));
|
||||
}
|
||||
building_doors[e->get()] = doors;
|
||||
scene->queue_delete();
|
||||
ps.unref();
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
void BuildingsData::get_scene_keys_list(List<String> *keys) const
|
||||
void BuildingsData::get_scene_keys_list(List<String> *keys)
|
||||
{
|
||||
ecs().each([keys](flecs::entity e, const CSceneData &d) {
|
||||
keys->push_back(String(e.name()));
|
||||
});
|
||||
}
|
||||
|
||||
bool BuildingsData::has_scene(const String &key) const
|
||||
bool BuildingsData::has_scene(const String &key)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
return e.is_valid();
|
||||
return e.is_valid() && e.has<CSceneData>();
|
||||
}
|
||||
|
||||
flecs::entity BuildingsData::get_building_entity(const String &key) const
|
||||
AABB BuildingsData::get_scene_aabb(const String &key)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
if (!e.is_valid()) {
|
||||
uint64_t key_hash = key.hash64();
|
||||
e = ecs().query_builder<const CSceneData>().build().find(
|
||||
[key_hash](const CSceneData &sd) {
|
||||
print_line("scene: " + sd.sd.key);
|
||||
return sd.sd.key.hash64() == key_hash;
|
||||
});
|
||||
if (!e.is_valid())
|
||||
print_line("scene not found: " + key);
|
||||
}
|
||||
assert(e.is_valid());
|
||||
if (!e.has<CSceneData>() || !e.has<CSceneAABB>())
|
||||
print_error("not found: " + key);
|
||||
assert(e.has<CSceneData>());
|
||||
|
||||
return e.get<CSceneAABB>()->aabb;
|
||||
}
|
||||
|
||||
flecs::entity BuildingsData::get_building_entity(const String &key)
|
||||
{
|
||||
flecs::query_builder<const CBuildingData> qb =
|
||||
ecs().query_builder<const CBuildingData>();
|
||||
@@ -689,6 +411,11 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
assert(e.is_valid());
|
||||
assert(e.has<CSceneData>());
|
||||
flecs::entity be = get_building_entity(bkey);
|
||||
assert(be.is_valid());
|
||||
assert(be.has<CBuildingData>());
|
||||
const CBuildingData *b = be.get<CBuildingData>();
|
||||
CSceneData *d = e.get_mut<CSceneData>();
|
||||
assert(d);
|
||||
String ename = "bi:" + bkey;
|
||||
@@ -697,54 +424,46 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
||||
if (ce.is_valid())
|
||||
ce.destruct();
|
||||
ce = ecs().entity(ename.ascii().ptr()).child_of(e);
|
||||
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||
Ref<PackedScene> ps = scene_get_packed_scene(key);
|
||||
if (!ps.is_valid())
|
||||
return;
|
||||
Node *where = SceneTree::get_singleton()->get_current_scene();
|
||||
assert(where);
|
||||
if (ps.is_valid()) {
|
||||
Spatial *scene = Object::cast_to<Spatial>(ps->instance());
|
||||
assert(scene);
|
||||
where->call_deferred("add_child", scene);
|
||||
scene->set_transform(b->building.xform);
|
||||
ce.set<CBuildingInstance>({ bkey, scene });
|
||||
} else
|
||||
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||
// print_line("child name: " + String(ce.name()));
|
||||
}
|
||||
|
||||
void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
||||
{
|
||||
if (!has_scene(key)) {
|
||||
flecs::entity e = ecs().entity(key.ascii().ptr());
|
||||
// print_line("scene key: " + key);
|
||||
assert(building_data.has(key));
|
||||
String path = building_data[key];
|
||||
// print_line("path: " + path);
|
||||
assert(path.length() > 5);
|
||||
print_line("Requesting " + (bkey) + " " + path);
|
||||
assert(!pending_scene.has(path));
|
||||
struct scene_data sd;
|
||||
sd.path = path;
|
||||
sd.loader = ResourceLoader::load_interactive(
|
||||
path, "PackedScene", true);
|
||||
assert(sd.loader.is_valid());
|
||||
e.set<CSceneData>({ sd });
|
||||
pending_scene.insert(path);
|
||||
assert(e.get_mut<CSceneData>());
|
||||
String ename = "bi:" + bkey;
|
||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||
if (ce.is_valid())
|
||||
ce.destruct();
|
||||
ce = ecs().entity(ename.ascii().ptr());
|
||||
ce.child_of(e);
|
||||
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||
// print_line("child name: " + String(ce.name()));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key) const
|
||||
Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
if (!e.has<CScenePackLoaded>())
|
||||
return Ref<PackedScene>();
|
||||
assert(e.is_valid());
|
||||
assert(e.has<CSceneData>());
|
||||
assert(e.has<CScenePack>());
|
||||
assert(e.get<CScenePack>());
|
||||
assert(e.get<CScenePack>()->sp.packed_scene.is_valid());
|
||||
|
||||
if (!e.is_valid())
|
||||
return Ref<PackedScene>();
|
||||
if (!e.get<CSceneData>())
|
||||
return Ref<PackedScene>();
|
||||
if (!e.get<CScenePack>())
|
||||
return Ref<PackedScene>();
|
||||
assert(e.is_valid());
|
||||
const CSceneData *d = e.get<CSceneData>();
|
||||
const CScenePack *d = e.get<CScenePack>();
|
||||
assert(d);
|
||||
return d->sd.packed_scene;
|
||||
return d->sp.packed_scene;
|
||||
}
|
||||
|
||||
int BuildingsData::scene_get_item_count(const String &key) const
|
||||
int BuildingsData::scene_get_item_count(const String &key)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
if (!e.is_valid())
|
||||
@@ -769,7 +488,7 @@ int BuildingsData::scene_get_item_count(const String &key) const
|
||||
// print_line("scene_get_item_count: " + itos(result));
|
||||
return result;
|
||||
}
|
||||
List<String> BuildingsData::scene_get_items(const String &key) const
|
||||
List<String> BuildingsData::scene_get_items(const String &key)
|
||||
{
|
||||
List<String> ret;
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
@@ -803,8 +522,9 @@ void BuildingsData::set_scene_item_node(const String &key, const String &bkey,
|
||||
assert(bi);
|
||||
assert(bi->key == bkey);
|
||||
bi->node = node;
|
||||
ce.modified<CBuildingInstance>();
|
||||
}
|
||||
bool BuildingsData::has_scene_item(const String &key, const String &bkey) const
|
||||
bool BuildingsData::has_scene_item(const String &key, const String &bkey)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
assert(e.is_valid());
|
||||
@@ -814,8 +534,7 @@ bool BuildingsData::has_scene_item(const String &key, const String &bkey) const
|
||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||
return ce.is_valid();
|
||||
}
|
||||
Node *BuildingsData::get_scene_item_node(const String &key,
|
||||
const String &bkey) const
|
||||
Node *BuildingsData::get_scene_item_node(const String &key, const String &bkey)
|
||||
{
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
assert(e.is_valid());
|
||||
@@ -823,6 +542,8 @@ Node *BuildingsData::get_scene_item_node(const String &key,
|
||||
assert(d);
|
||||
String ename = "bi:" + bkey;
|
||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||
if (!ce.is_valid()) /* no instance */
|
||||
return nullptr;
|
||||
assert(ce.is_valid());
|
||||
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
|
||||
assert(bi);
|
||||
@@ -836,7 +557,7 @@ void BuildingsData::save_buildings()
|
||||
save_buildings_json(buildings_path);
|
||||
}
|
||||
|
||||
Node *BuildingsData::item_nodes_get_node(const String &key) const
|
||||
Node *BuildingsData::item_nodes_get_node(const String &key)
|
||||
{
|
||||
flecs::query_builder<const CBuildingInstance> qb =
|
||||
ecs().query_builder<const CBuildingInstance>();
|
||||
@@ -851,29 +572,6 @@ Node *BuildingsData::item_nodes_get_node(const String &key) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Error BuildingsData::scene_loader_poll(const String &key)
|
||||
{
|
||||
if (has_scene(key)) {
|
||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||
assert(e.is_valid());
|
||||
CSceneData *d = e.get_mut<CSceneData>();
|
||||
assert(d);
|
||||
assert(d->sd.loader.is_valid());
|
||||
Error err = d->sd.loader->poll();
|
||||
if (err == ERR_FILE_EOF || err == OK) {
|
||||
Ref<PackedScene> sc = d->sd.loader->get_resource();
|
||||
d->sd.packed_scene = sc;
|
||||
print_line("Loaded scene: " + d->sd.path + " OK");
|
||||
return OK;
|
||||
} else {
|
||||
print_error("Could not load the resource :( " +
|
||||
d->sd.path + " " + itos(err));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
void BuildingsData::scene_update()
|
||||
{
|
||||
List<String> keys;
|
||||
@@ -885,12 +583,11 @@ void BuildingsData::scene_update()
|
||||
e = e->next();
|
||||
continue;
|
||||
}
|
||||
scene_loader_poll(key);
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
int BuildingsData::get_building_count() const
|
||||
int BuildingsData::get_building_count()
|
||||
{
|
||||
flecs::query<const CBuildingData> q =
|
||||
ecs().query<const CBuildingData>();
|
||||
@@ -906,20 +603,24 @@ int BuildingsData::get_building_count() const
|
||||
return result;
|
||||
}
|
||||
|
||||
const struct BuildingsData::building &
|
||||
BuildingsData::get_building(const String &building_key) const
|
||||
{
|
||||
String ename = "base:" + building_key;
|
||||
flecs::entity e = lookup(ename);
|
||||
assert(e.is_valid());
|
||||
return e.get<CBuildingData>()->building;
|
||||
}
|
||||
|
||||
struct BuildingsData::building &
|
||||
BuildingsData::get_building(const String &building_key)
|
||||
{
|
||||
String ename = "base:" + building_key;
|
||||
flecs::entity e = lookup(ename);
|
||||
if (!e.is_valid()) {
|
||||
// print_error("bad building: " + ename);
|
||||
e = ecs().query_builder<const CBuildingData>().build().find(
|
||||
[&](flecs::entity se, const CBuildingData &bd) {
|
||||
// print_line(String(se.name() + "#" +
|
||||
// bd.building.key));
|
||||
if (bd.building.key == building_key)
|
||||
return true;
|
||||
if (String(se.name()) == ename)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
assert(e.is_valid());
|
||||
return e.get_mut<CBuildingData>()->building;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <core/reference.h>
|
||||
#include <scene/resources/packed_scene.h>
|
||||
#include <core/io/config_file.h>
|
||||
#include <flecs.h>
|
||||
class PackedScene;
|
||||
class ResourceInteractiveLoader;
|
||||
class BuildingsData {
|
||||
static ConfigFile config;
|
||||
|
||||
public:
|
||||
/* Per-building information */
|
||||
struct building {
|
||||
@@ -23,6 +27,15 @@ public:
|
||||
Dictionary to_dict() const;
|
||||
String line_name;
|
||||
};
|
||||
struct scene_data {
|
||||
String key;
|
||||
String path;
|
||||
};
|
||||
struct scene_pack {
|
||||
Ref<PackedScene> packed_scene;
|
||||
Ref<ResourceInteractiveLoader> loader;
|
||||
};
|
||||
|
||||
Set<String> pending_scene;
|
||||
/* Scene objects data */
|
||||
//private:
|
||||
@@ -31,6 +44,9 @@ public:
|
||||
struct CBuildingData {
|
||||
struct BuildingsData::building building;
|
||||
};
|
||||
struct CBuildingSceneLoaded {};
|
||||
struct CBuildingSceneLoad {};
|
||||
struct CBuildingSceneUnload {};
|
||||
struct CBTypeResidental {};
|
||||
struct CBCustomLayout {
|
||||
int size;
|
||||
@@ -65,39 +81,54 @@ public:
|
||||
struct CBuildingUnload {};
|
||||
struct CBuildingLoaded {};
|
||||
struct CBuildingEdited {};
|
||||
struct CSceneData {
|
||||
struct scene_data sd;
|
||||
};
|
||||
struct CScenePack {
|
||||
struct scene_pack sp;
|
||||
};
|
||||
struct CScenePackLoaded {};
|
||||
struct CSceneDoors {
|
||||
Vector<Transform> doors;
|
||||
};
|
||||
struct CSceneAABB {
|
||||
AABB aabb;
|
||||
};
|
||||
struct CScenesLoaded {}; /* all scenes loaded */
|
||||
struct CBuildingInstance {
|
||||
String key;
|
||||
Node *node;
|
||||
};
|
||||
struct CBuildingInstanced {};
|
||||
|
||||
public:
|
||||
void get_scene_keys_list(List<String> *keys) const;
|
||||
bool has_scene(const String &key) const;
|
||||
void remove_scene_item(const String &key, const String &bkey);
|
||||
void add_scene_item(const String &key, const String &bkey);
|
||||
void create_scene_data(const String &key, const String &bkey);
|
||||
Ref<PackedScene> scene_get_packed_scene(const String &key) const;
|
||||
int scene_get_item_count(const String &key) const;
|
||||
static void get_scene_keys_list(List<String> *keys);
|
||||
static bool has_scene(const String &key);
|
||||
static AABB get_scene_aabb(const String &key);
|
||||
static void remove_scene_item(const String &key, const String &bkey);
|
||||
static void add_scene_item(const String &key, const String &bkey);
|
||||
static Ref<PackedScene> scene_get_packed_scene(const String &key);
|
||||
static int scene_get_item_count(const String &key);
|
||||
// String scene_get_item(const String &key, int index) const;
|
||||
List<String> scene_get_items(const String &key) const;
|
||||
void set_scene_item_node(const String &key, const String &bkey,
|
||||
Node *node);
|
||||
bool has_scene_item(const String &key, const String &bkey) const;
|
||||
Node *get_scene_item_node(const String &key, const String &bkey) const;
|
||||
void save_buildings();
|
||||
static List<String> scene_get_items(const String &key);
|
||||
static void set_scene_item_node(const String &key, const String &bkey,
|
||||
Node *node);
|
||||
static bool has_scene_item(const String &key, const String &bkey);
|
||||
static Node *get_scene_item_node(const String &key, const String &bkey);
|
||||
static void save_buildings();
|
||||
|
||||
public:
|
||||
Node *item_nodes_get_node(const String &key) const;
|
||||
|
||||
private:
|
||||
Error scene_loader_poll(const String &key);
|
||||
static Node *item_nodes_get_node(const String &key);
|
||||
|
||||
public:
|
||||
void scene_update();
|
||||
static void scene_update();
|
||||
/* Path for each building type */
|
||||
HashMap<String, String> building_data;
|
||||
HashMap<String, Vector<Transform> > building_doors;
|
||||
HashMap<String, AABB> building_aabbs;
|
||||
// HashMap<String, String> building_data;
|
||||
// HashMap<String, Vector<Transform> > building_doors;
|
||||
// HashMap<String, AABB> building_aabbs;
|
||||
|
||||
public:
|
||||
struct building &get_building(const String &building_key);
|
||||
const struct building &get_building(const String &building_key) const;
|
||||
static struct building &get_building(const String &building_key);
|
||||
struct callme {
|
||||
class H {};
|
||||
H *obj;
|
||||
@@ -126,8 +157,9 @@ public:
|
||||
void *)>(obj);
|
||||
}
|
||||
|
||||
void for_each_building(struct callme &c);
|
||||
template <typename Func> void for_each_building(Func &&func, void *data)
|
||||
static void for_each_building(struct callme &c);
|
||||
template <typename Func>
|
||||
static void for_each_building(Func &&func, void *data)
|
||||
{
|
||||
List<String> keys;
|
||||
get_building_keys_list(&keys);
|
||||
@@ -137,40 +169,41 @@ public:
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
void for_each_building(void (*func)(const String &key, void *data),
|
||||
void *data);
|
||||
void get_building_keys_list(List<String> *keys);
|
||||
static void for_each_building(void (*func)(const String &key,
|
||||
void *data),
|
||||
void *data);
|
||||
static void get_building_keys_list(List<String> *keys);
|
||||
|
||||
int get_building_count() const;
|
||||
String create_building(const Dictionary &dict);
|
||||
String create_building(const struct building &building);
|
||||
String create_building(const struct building *building);
|
||||
bool destroy_building(const String &key);
|
||||
static int get_building_count();
|
||||
static String create_building(const Dictionary &dict);
|
||||
static String create_building(const struct building &building);
|
||||
static String create_building(const struct building *building);
|
||||
static bool destroy_building(const String &key);
|
||||
struct checkpoint_data {
|
||||
HashMap<String, String> building_data;
|
||||
std::vector<struct building> buildings;
|
||||
};
|
||||
std::vector<struct checkpoint_data> undo_log;
|
||||
int undo_log_size;
|
||||
BuildingsData();
|
||||
BuildingsData(flecs::world &e);
|
||||
virtual ~BuildingsData();
|
||||
|
||||
public:
|
||||
void read_buildings_json(const String &buildings_path);
|
||||
void save_buildings_json(const String &buildings_path);
|
||||
void filter_generated_stuff();
|
||||
void remove_generated_stuff();
|
||||
static void read_buildings_json(const String &buildings_path);
|
||||
static void save_buildings_json(const String &buildings_path);
|
||||
static void filter_generated_stuff();
|
||||
static void remove_generated_stuff();
|
||||
void load_data();
|
||||
void checkpoint();
|
||||
void undo();
|
||||
void fill_door_locations();
|
||||
void build_building_aabbs();
|
||||
void update_building_transform(const String &key,
|
||||
const Transform &xform);
|
||||
bool has_building(const String &key);
|
||||
String get_closest_building(const Transform &xform) const;
|
||||
flecs::entity get_closest_building_entity(const Transform &xform) const;
|
||||
flecs::entity get_building_entity(const String &key) const;
|
||||
static void build_building_aabbs();
|
||||
static void update_building_transform(const String &key,
|
||||
const Transform &xform);
|
||||
static bool has_building(const String &key);
|
||||
static String get_closest_building(const Transform &xform);
|
||||
static flecs::entity
|
||||
get_closest_building_entity(const Transform &xform);
|
||||
static flecs::entity get_building_entity(const String &key);
|
||||
void load_tile(int x, int z);
|
||||
};
|
||||
#endif
|
||||
400
src/modules/stream/buildings_data_module.cpp
Normal file
400
src/modules/stream/buildings_data_module.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
#include <scene/resources/packed_scene.h>
|
||||
#include <scene/3d/spatial.h>
|
||||
#include <scene/3d/mesh_instance.h>
|
||||
#include <scene/3d/camera.h>
|
||||
#include <scene/main/viewport.h>
|
||||
#include "base_data.h"
|
||||
#include "buildings_data.h"
|
||||
|
||||
static flecs::world &ecs()
|
||||
{
|
||||
return BaseData::get_singleton()->get();
|
||||
}
|
||||
|
||||
BuildingsData::BuildingsData(flecs::world &ecs_)
|
||||
: undo_log_size(64)
|
||||
{
|
||||
ecs_.module<BuildingsData>();
|
||||
// print_line("e0");
|
||||
// flecs::world ecs_ = ecs();
|
||||
ecs_.component<CBuildingStats>();
|
||||
ecs_.component<CBuildingData>();
|
||||
ecs_.component<CBTypeResidental>();
|
||||
ecs_.component<CBCustomLayout>();
|
||||
ecs_.component<CBuildingEdited>();
|
||||
ecs_.component<CBuildingTileData>();
|
||||
ecs_.component<CBuildingLoaded>();
|
||||
ecs_.component<CBuildingsEye>();
|
||||
ecs_.component<CSceneData>();
|
||||
ecs_.component<CScenePack>();
|
||||
ecs_.component<CScenesLoaded>();
|
||||
ecs_.component<CSceneAABB>();
|
||||
// print_line("e1");
|
||||
// bool deferred = ecs_.is_deferred();
|
||||
// if (deferred)
|
||||
// ecs_.defer_suspend();
|
||||
ecs_.set<CBuildingStats>({ 0 });
|
||||
ecs_.set<CBuildingTileData>({});
|
||||
assert(ecs_.has<CBuildingStats>());
|
||||
load_data();
|
||||
print_line("=== buildings");
|
||||
ecs_.query_builder<const CBuildingData>().build().each(
|
||||
[](flecs::entity e, const CBuildingData &bd) {
|
||||
print_line("created: building: " + bd.building.key +
|
||||
" / " + String(e.name()));
|
||||
});
|
||||
/* no scene data loaded yet */
|
||||
print_line("=== scenes");
|
||||
ecs_.query_builder<const CSceneData>().build().each(
|
||||
[](flecs::entity e, const CSceneData &sd) {
|
||||
print_line("created: scene: " + sd.sd.path + " / " +
|
||||
String(e.name()));
|
||||
});
|
||||
print_line("loaded buildings: " +
|
||||
itos(ecs().get<CBuildingStats>()->created_entities));
|
||||
assert(ecs().get<CBuildingStats>()->created_entities > 0);
|
||||
|
||||
/* Fill door locations */
|
||||
ecs().query_builder<CSceneData>().build().each([&](flecs::entity e,
|
||||
CSceneData &sd) {
|
||||
Error err;
|
||||
const String &path = sd.sd.path;
|
||||
Ref<PackedScene> ps =
|
||||
ResourceLoader::load(path, "PackedScene", true, &err);
|
||||
if (err == OK && ps.is_valid()) {
|
||||
Vector<Transform> doors;
|
||||
Node *scene = ps->instance();
|
||||
List<Node *> queue;
|
||||
queue.push_back(scene);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
Node *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
String name = item->get_name();
|
||||
if (name.find("-portal") >= 0) {
|
||||
Spatial *sp =
|
||||
Object::cast_to<Spatial>(item);
|
||||
if (sp) {
|
||||
Transform xform =
|
||||
sp->get_transform();
|
||||
Node *tmp = item->get_parent();
|
||||
while (tmp) {
|
||||
Transform parent_xform;
|
||||
Spatial *parent_sp =
|
||||
Object::cast_to<
|
||||
Spatial>(
|
||||
tmp);
|
||||
if (parent_sp)
|
||||
parent_xform =
|
||||
parent_sp
|
||||
->get_transform();
|
||||
xform = parent_xform *
|
||||
xform;
|
||||
tmp = tmp->get_parent();
|
||||
}
|
||||
doors.push_back(xform);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < item->get_child_count(); i++)
|
||||
queue.push_back(item->get_child(i));
|
||||
}
|
||||
e.set<CSceneDoors>({ doors });
|
||||
scene->queue_delete();
|
||||
ps.unref();
|
||||
}
|
||||
});
|
||||
// if (deferred)
|
||||
// ecs_.defer_resume();
|
||||
ecs_.system("CreateSceneData")
|
||||
.kind(flecs::OnUpdate)
|
||||
.write<CSceneData>()
|
||||
.run([&](flecs::iter &it) {
|
||||
Dictionary buildings_data =
|
||||
config.get_value("buildings", "building_data");
|
||||
List<Variant> keys;
|
||||
buildings_data.get_key_list(&keys);
|
||||
List<Variant>::Element *e = keys.front();
|
||||
while (e) {
|
||||
String key = e->get();
|
||||
if (!has_scene(key)) {
|
||||
// building_data[key] = buildings_data[key];
|
||||
String path = buildings_data[key];
|
||||
flecs::entity se =
|
||||
ecs().entity(key.ascii().ptr());
|
||||
se.set<CSceneData>({ key, path });
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
});
|
||||
ecs_.system<const CSceneData>("LoadPackedScene")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<CScenePack>()
|
||||
.write<CScenePack>()
|
||||
.each([&](flecs::entity e, const CSceneData &sd) {
|
||||
struct scene_pack sp;
|
||||
sp.loader = ResourceLoader::load_interactive(
|
||||
sd.sd.path, "PackedScene", true);
|
||||
assert(sp.loader.is_valid());
|
||||
e.set<CScenePack>({ sp });
|
||||
});
|
||||
ecs_.system<CScenePack>("LoadPackedScenePoll")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<CScenePackLoaded>()
|
||||
.each([&](flecs::entity e, CScenePack &sp) {
|
||||
const CSceneData *sd = e.get<CSceneData>();
|
||||
assert(sd);
|
||||
assert(sp.sp.loader.is_valid());
|
||||
Error err = sp.sp.loader->poll();
|
||||
if (err == OK) {
|
||||
return;
|
||||
} else if (err == ERR_FILE_EOF) {
|
||||
Ref<PackedScene> sc =
|
||||
sp.sp.loader->get_resource();
|
||||
sp.sp.packed_scene = sc;
|
||||
uint64_t m_id = (uint64_t)&sp.sp.loader;
|
||||
print_line("Loaded scene: " + sd->sd.path +
|
||||
" OK " +
|
||||
String::num_int64(m_id, 16));
|
||||
e.add<CScenePackLoaded>();
|
||||
assert(sp.sp.packed_scene.is_valid());
|
||||
} else {
|
||||
print_error("Could not load the resource :( " +
|
||||
sd->sd.path + " " + itos(err));
|
||||
}
|
||||
});
|
||||
ecs_.system<CSceneData>("CalculateAABBs")
|
||||
.without<CSceneAABB>()
|
||||
.each([&](flecs::entity e, CSceneData &sd) {
|
||||
Error err;
|
||||
const String &path = sd.sd.path;
|
||||
Ref<PackedScene> ps = ResourceLoader::load(
|
||||
path, "PackedScene", true, &err);
|
||||
if (err == OK && ps.is_valid()) {
|
||||
AABB aabb;
|
||||
Node *scene = ps->instance();
|
||||
List<Node *> queue;
|
||||
queue.push_back(scene);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
Node *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
MeshInstance *mi =
|
||||
Object::cast_to<MeshInstance>(
|
||||
item);
|
||||
if (mi) {
|
||||
if (aabb.size.length_squared() <
|
||||
0.1f)
|
||||
aabb = mi->get_aabb();
|
||||
else
|
||||
aabb.merge_with(
|
||||
mi->get_aabb());
|
||||
}
|
||||
for (i = 0; i < item->get_child_count();
|
||||
i++)
|
||||
queue.push_back(
|
||||
item->get_child(i));
|
||||
}
|
||||
scene->queue_delete();
|
||||
ps.unref();
|
||||
e.set<CSceneAABB>({ aabb });
|
||||
|
||||
} else
|
||||
print_error("Could not load: " + path);
|
||||
});
|
||||
ecs_.system("CheckScenesLoaded")
|
||||
.kind(flecs::OnUpdate)
|
||||
.run([&](flecs::iter &it) {
|
||||
int count_csdata = (int)it.world()
|
||||
.query_builder<CSceneData>()
|
||||
.build()
|
||||
.count();
|
||||
int count_pack =
|
||||
(int)it.world()
|
||||
.query_builder<CScenePackLoaded>()
|
||||
.build()
|
||||
.count();
|
||||
int count_aabb = (int)it.world()
|
||||
.query_builder<CSceneAABB>()
|
||||
.build()
|
||||
.count();
|
||||
if (count_csdata > 0 && count_csdata == count_pack &&
|
||||
count_csdata == count_aabb)
|
||||
it.world().add<CScenesLoaded>();
|
||||
else
|
||||
it.world().remove<CScenesLoaded>();
|
||||
});
|
||||
ecs_.observer<CBuildingInstance>()
|
||||
.event(flecs::OnRemove)
|
||||
.each([](flecs::entity e, CBuildingInstance &bi) {
|
||||
if (bi.node) {
|
||||
bi.node->queue_delete();
|
||||
bi.node = nullptr;
|
||||
// print_line("instance destroyed for " + bi.key);
|
||||
}
|
||||
});
|
||||
ecs_.observer<CBuildingEdited>()
|
||||
.event(flecs::OnAdd)
|
||||
.with<CBuildingData>()
|
||||
.run([&](flecs::iter &it) {
|
||||
flecs::query<const CBuildingData> q =
|
||||
it.world()
|
||||
.query_builder<const CBuildingData>()
|
||||
.with<CBuildingEdited>()
|
||||
.build();
|
||||
if (it.next()) {
|
||||
flecs::entity qe = it.entity(0);
|
||||
q.each([qe](flecs::entity e,
|
||||
const CBuildingData &d) {
|
||||
if (e != qe)
|
||||
e.remove<CBuildingEdited>();
|
||||
});
|
||||
print_line("Selected building " +
|
||||
String(qe.name()));
|
||||
// it.fini();
|
||||
}
|
||||
});
|
||||
ecs_.system("UpdateEye").kind(flecs::OnUpdate).run([&](flecs::iter &it) {
|
||||
Viewport *viewport = SceneTree::get_singleton()
|
||||
->get_current_scene()
|
||||
->get_viewport();
|
||||
int i, j, l;
|
||||
int tile_size = config.get_value("world", "tile_size");
|
||||
int view_distance = config.get_value("world", "view_distance");
|
||||
assert(tile_size > 0);
|
||||
Transform xform =
|
||||
viewport->get_camera()->get_global_transform();
|
||||
Vector3 eye = xform.origin;
|
||||
int tile_x = int(eye.x / tile_size);
|
||||
int tile_z = int(eye.z / tile_size);
|
||||
bool need_update = true;
|
||||
if (it.world().has<CBuildingsEye>()) {
|
||||
int old_x = it.world().get<CBuildingsEye>()->tile_x;
|
||||
int old_z = it.world().get<CBuildingsEye>()->tile_z;
|
||||
if (old_x == tile_x && old_z == tile_z)
|
||||
need_update = false;
|
||||
else
|
||||
print_line("UpdateEye need update");
|
||||
}
|
||||
it.world().set<CBuildingsEye>({ xform, tile_x, tile_z });
|
||||
if (!need_update)
|
||||
return;
|
||||
if (!it.world().has<CBuildingTileData>())
|
||||
return;
|
||||
CBuildingTileData *td = it.world().get_mut<CBuildingTileData>();
|
||||
it.world()
|
||||
.query_builder<CBuildingData>()
|
||||
.without<CBuildingLoaded>()
|
||||
.without<CBuildingLoad>()
|
||||
.with<CBuildingTile>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
const CBuildingTile *bt =
|
||||
e.get<CBuildingTile>();
|
||||
std::tuple<int, int> tile = bt->tile;
|
||||
int t_x = std::get<0>(tile);
|
||||
int t_z = std::get<1>(tile);
|
||||
if (t_x > tile_x - view_distance &&
|
||||
t_x < tile_x + view_distance &&
|
||||
t_z > tile_z - view_distance &&
|
||||
t_z < tile_z + view_distance) {
|
||||
if (e.is_valid()) {
|
||||
print_line("CBuildingLoad");
|
||||
e.add<BuildingsData::
|
||||
CBuildingLoad>();
|
||||
}
|
||||
}
|
||||
});
|
||||
it.world()
|
||||
.query_builder<CBuildingData>()
|
||||
.with<CBuildingLoaded>()
|
||||
.with<CBuildingTile>()
|
||||
.without<CBuildingUnload>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
const CBuildingTile *bt =
|
||||
e.get<CBuildingTile>();
|
||||
std::tuple<int, int> tile = bt->tile;
|
||||
int erase_distance = view_distance + 1;
|
||||
int ed2 = erase_distance * erase_distance;
|
||||
|
||||
int t_x = std::get<0>(tile);
|
||||
int t_z = std::get<1>(tile);
|
||||
int d1 = t_x - tile_x;
|
||||
int d2 = t_z - tile_z;
|
||||
if (d1 * d1 > ed2 || d2 * d2 > ed2)
|
||||
if (e.is_valid()) {
|
||||
print_line("CBuildingUnload");
|
||||
e.add<BuildingsData::
|
||||
CBuildingUnload>();
|
||||
}
|
||||
});
|
||||
});
|
||||
ecs_.system<const CBuildingData>("LoadData")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<CBuildingLoaded>()
|
||||
.without<CBuildingUnload>()
|
||||
.with<CBuildingLoad>()
|
||||
.write<CBuildingLoaded>()
|
||||
.write<CBuildingLoad>()
|
||||
.write<CBuildingInstanced>()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
bool debug = false;
|
||||
// if (bd.building.key.begins_with("road__"))
|
||||
// debug = true;
|
||||
String id = bd.building.id;
|
||||
if (debug)
|
||||
print_verbose("add to scene id: " + id);
|
||||
if (!SceneTree::get_singleton()->get_current_scene())
|
||||
return;
|
||||
if (!scene_get_packed_scene(id).is_valid())
|
||||
return;
|
||||
if (!has_scene(id))
|
||||
return;
|
||||
else {
|
||||
if (!e.has<CBuildingInstanced>()) {
|
||||
add_scene_item(id, bd.building.key);
|
||||
e.add<CBuildingInstanced>();
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
print_verbose("added to scene id: " + id);
|
||||
assert(e.is_valid());
|
||||
// e.world().defer_suspend();
|
||||
e.add<CBuildingLoaded>();
|
||||
e.remove<CBuildingLoad>();
|
||||
print_line("CBuildingLoaded");
|
||||
// e.world().defer_resume();
|
||||
print_line("LoadData");
|
||||
});
|
||||
ecs_.system<const CBuildingData>("UnloadData")
|
||||
.kind(flecs::OnUpdate)
|
||||
.read<CBuildingInstanced>()
|
||||
.with<CBuildingUnload>()
|
||||
.with<CBuildingLoaded>()
|
||||
.write<CBuildingLoaded>()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {
|
||||
bool debug = false;
|
||||
// if (bd.building.key.begins_with("road__"))
|
||||
// debug = true;
|
||||
String id = bd.building.key;
|
||||
if (debug)
|
||||
print_verbose("removed from scene id: " + id);
|
||||
if (has_scene(id))
|
||||
remove_scene_item(id, bd.building.key);
|
||||
e.remove<CBuildingLoaded>();
|
||||
e.remove<CBuildingUnload>();
|
||||
e.remove<CBuildingInstanced>();
|
||||
print_line("UnloadData");
|
||||
});
|
||||
ecs_.system<const CBuildingData>("SpawnNode")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<CBuildingUnload>()
|
||||
.with<CBuildingLoaded>()
|
||||
.write<CBuildingLoaded>()
|
||||
.each([&](flecs::entity e, const CBuildingData &bd) {});
|
||||
print_line("SpawnNode initialized");
|
||||
}
|
||||
|
||||
BuildingsData::~BuildingsData()
|
||||
{
|
||||
}
|
||||
@@ -4,28 +4,28 @@
|
||||
#include <scene/3d/immediate_geometry.h>
|
||||
#include "wedge.h"
|
||||
#include "base_data.h"
|
||||
#include "buildings_data.h"
|
||||
#include "contours.h"
|
||||
|
||||
Contours *Contours::singleton = nullptr;
|
||||
|
||||
Contours *Contours::get_singleton()
|
||||
{
|
||||
if (!singleton)
|
||||
singleton = memnew(Contours);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
Contours::Contours()
|
||||
Contours::Contours(flecs::world &ecs)
|
||||
: dbg(nullptr)
|
||||
{
|
||||
BaseData::get_singleton()->get().component<Lot>();
|
||||
ecs.module<Contours>();
|
||||
ecs.import <BuildingsData>();
|
||||
Lot::import_packer(ecs);
|
||||
ecs.component<Lot>();
|
||||
base_e = BaseData::get_singleton()->get().lookup("lots");
|
||||
if (base_e.is_valid())
|
||||
base_e.destruct();
|
||||
base_e = BaseData::get_singleton()->get().entity("lots");
|
||||
assert(base_e.is_valid());
|
||||
}
|
||||
|
||||
Contours::~Contours()
|
||||
{
|
||||
}
|
||||
|
||||
bool Contours::is_in_closed_contour(const struct wedge *w)
|
||||
bool Contours::is_in_closed_contour(const struct wedge *w) const
|
||||
{
|
||||
int i, j;
|
||||
bool found = false;
|
||||
@@ -51,6 +51,7 @@ static Vector3 normal(const Vector3 &v)
|
||||
void Contours::build()
|
||||
{
|
||||
int i, j;
|
||||
print_line("Contours::build()");
|
||||
contours.clear();
|
||||
for (i = 0; i < (int)wedge_contours.size(); i++) {
|
||||
struct main_contour mc;
|
||||
@@ -86,10 +87,6 @@ void Contours::build()
|
||||
}
|
||||
contours.push_back(mc);
|
||||
}
|
||||
flecs::entity base_e = BaseData::get_singleton()->get().lookup("lots");
|
||||
if (base_e.is_valid())
|
||||
base_e.destruct();
|
||||
base_e = BaseData::get_singleton()->get().entity("lots");
|
||||
List<struct Lot::polygon> polygon_queue;
|
||||
List<struct Lot::polygon> polygon_output;
|
||||
Vector<struct Lot::polygon> check;
|
||||
@@ -141,7 +138,7 @@ void Contours::build()
|
||||
List<struct Lot::polygon>::Element *e = polygon_queue.front();
|
||||
while (e) {
|
||||
struct Lot::polygon item = e->get();
|
||||
print_line("queue: " + itos(polygon_queue.size()));
|
||||
// print_line("queue: " + itos(polygon_queue.size()));
|
||||
polygon_queue.pop_front();
|
||||
float area = item.area();
|
||||
if (area > 120.0f * 120.0f &&
|
||||
@@ -162,12 +159,15 @@ void Contours::build()
|
||||
e = polygon_queue.front();
|
||||
}
|
||||
e = polygon_output.front();
|
||||
assert(base_e.is_valid());
|
||||
while (e) {
|
||||
print_line("creating entity");
|
||||
flecs::entity lot_e = BaseData::get_singleton()
|
||||
->get()
|
||||
.entity()
|
||||
.child_of(base_e);
|
||||
lot_e.set<Lot>({ e->get() });
|
||||
print_line("created entity: " + String(lot_e.name()));
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,6 @@ void Contours::build()
|
||||
}
|
||||
});
|
||||
});
|
||||
Lot::pack();
|
||||
}
|
||||
|
||||
void Contours::debug()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef CONTOURS_H_
|
||||
#define CONTOURS_H_
|
||||
#include <vector>
|
||||
#include <flecs.h>
|
||||
#include "road_lot.h"
|
||||
|
||||
class ImmediateGeometry;
|
||||
@@ -20,12 +21,11 @@ struct Contours {
|
||||
Ref<SpatialMaterial> imm_mat;
|
||||
std::vector<std::vector<struct wedge *> > wedge_contours;
|
||||
std::vector<struct main_contour> contours;
|
||||
static Contours *singleton;
|
||||
static Contours *get_singleton();
|
||||
Contours();
|
||||
Contours(flecs::world &ecs);
|
||||
virtual ~Contours();
|
||||
bool is_in_closed_contour(const struct wedge *w);
|
||||
bool is_in_closed_contour(const struct wedge *w) const;
|
||||
void debug();
|
||||
flecs::entity base_e;
|
||||
};
|
||||
|
||||
#endif // CONTOURS_H_
|
||||
@@ -26,6 +26,7 @@ LineMetadataEditor::~LineMetadataEditor()
|
||||
|
||||
void LineMetadataEditor::_notification(int which)
|
||||
{
|
||||
#if 0
|
||||
switch (which) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
VBoxContainer *box = memnew(VBoxContainer);
|
||||
@@ -64,6 +65,7 @@ void LineMetadataEditor::_notification(int which)
|
||||
}
|
||||
} break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LineMetadataEditor::_bind_methods()
|
||||
|
||||
@@ -1125,7 +1125,7 @@ class EdgeEditorHandler {
|
||||
continue;
|
||||
}
|
||||
const AABB &aabb_building =
|
||||
bd()->building_aabbs[buildings[i].id];
|
||||
bd()->get_scene_aabb(buildings[i].id);
|
||||
Transform building_rot(
|
||||
Basis().rotated(
|
||||
Vector3(0, 1, 0),
|
||||
@@ -1306,9 +1306,9 @@ class EdgeEditorHandler {
|
||||
String lot_id = side.lot_type;
|
||||
if (side.buildings.size() > 1) {
|
||||
const AABB &aabb_lot =
|
||||
bd()->building_aabbs
|
||||
["lot-" +
|
||||
lot_id];
|
||||
bd()->get_scene_aabb(
|
||||
"lot-" +
|
||||
lot_id);
|
||||
bool pack_result =
|
||||
pack_buildings(
|
||||
aabb_lot,
|
||||
@@ -1375,9 +1375,9 @@ class EdgeEditorHandler {
|
||||
String lot_id = side.lot_type;
|
||||
if (side.buildings.size() > 1) {
|
||||
const AABB &aabb_lot =
|
||||
bd()->building_aabbs
|
||||
["lot-" +
|
||||
lot_id];
|
||||
bd()->get_scene_aabb(
|
||||
"lot-" +
|
||||
lot_id);
|
||||
bool pack_result =
|
||||
pack_buildings(
|
||||
aabb_lot,
|
||||
|
||||
@@ -121,9 +121,9 @@ template <typename T> static Vector<Vector2> get_polygon2(const T &polygon)
|
||||
|
||||
bool Lot::polygon::intersects(const polygon *other) const
|
||||
{
|
||||
print_line("intersection_test");
|
||||
dump();
|
||||
other->dump();
|
||||
// print_line("intersection_test");
|
||||
// dump();
|
||||
// other->dump();
|
||||
Vector<Vector2> p1 = get_polygon2(points);
|
||||
Vector<Vector2> p2 = get_polygon2(other->points);
|
||||
Vector<Vector<Vector2> > intersection =
|
||||
@@ -510,14 +510,16 @@ struct LotPacker {
|
||||
lbs.clear();
|
||||
Array lb = config.get_value("road", varname, Array());
|
||||
int i, j;
|
||||
print_line("start building list");
|
||||
for (i = 0; i < (int)lb.size(); i++) {
|
||||
struct config_buildings cb;
|
||||
cb.area = 0.0f;
|
||||
Array entries = lb[i];
|
||||
for (j = 0; j < entries.size(); j++) {
|
||||
String bname = entries[j];
|
||||
print_line("building: " + bname);
|
||||
cb.buildings.push_back(bname);
|
||||
AABB aabb = get_building_type_aabb(bname);
|
||||
AABB aabb = bd()->get_scene_aabb(bname);
|
||||
cb.area += aabb.size.x * aabb.size.z;
|
||||
print_line("config building: " + bname);
|
||||
}
|
||||
@@ -525,6 +527,7 @@ struct LotPacker {
|
||||
String::num(cb.area));
|
||||
lbs.push_back(cb);
|
||||
}
|
||||
print_line("end building list");
|
||||
struct lbsort {
|
||||
_FORCE_INLINE_ bool
|
||||
operator()(const struct config_buildings &b1,
|
||||
@@ -536,29 +539,45 @@ struct LotPacker {
|
||||
lbs.sort_custom<struct lbsort>();
|
||||
lbs.invert();
|
||||
}
|
||||
LotPacker(Vector2 cell_size)
|
||||
: cell_size(cell_size)
|
||||
LotPacker(flecs::world &ecs)
|
||||
: cell_size(Vector2(16, 16))
|
||||
{
|
||||
BaseData::get_singleton()->get().component<LotGrid>();
|
||||
BaseData::get_singleton()->get().component<LotBuildings>();
|
||||
BaseData::get_singleton()->get().component<PreOccupied>();
|
||||
BaseData::get_singleton()->get().component<Industrial>();
|
||||
BaseData::get_singleton()->get().component<Commercial>();
|
||||
BaseData::get_singleton()->get().component<Residental>();
|
||||
ecs.module<LotPacker>();
|
||||
ecs.import <BuildingsData>();
|
||||
ecs.component<LotGrid>();
|
||||
ecs.component<PreOccupied>();
|
||||
ecs.component<Industrial>();
|
||||
ecs.component<Commercial>();
|
||||
ecs.component<Residental>();
|
||||
struct PackerState {
|
||||
int state;
|
||||
};
|
||||
ecs.component<PackerState>();
|
||||
|
||||
Error err = config.load("res://config/stream.conf");
|
||||
assert(err == OK);
|
||||
get_building_list("lot_buildings_residental",
|
||||
lot_buildings_residental);
|
||||
get_building_list("lot_buildings_commercial",
|
||||
lot_buildings_commercial);
|
||||
get_building_list("lot_buildings_industrial",
|
||||
lot_buildings_industrial);
|
||||
}
|
||||
static LotPacker *get_singleton()
|
||||
{
|
||||
if (!singleton)
|
||||
singleton = memnew(LotPacker(Vector2(16, 16)));
|
||||
return singleton;
|
||||
ecs.system("MakeStuff")
|
||||
.kind(flecs::OnUpdate)
|
||||
.run([&](flecs::iter &it) {
|
||||
if (!it.world().has<PackerState>())
|
||||
it.world().set<PackerState>({ 0 });
|
||||
if (it.world().has<PackerState>() &&
|
||||
it.world().get<PackerState>()->state == 1) {
|
||||
get_building_list(
|
||||
"lot_buildings_residental",
|
||||
lot_buildings_residental);
|
||||
get_building_list(
|
||||
"lot_buildings_commercial",
|
||||
lot_buildings_commercial);
|
||||
get_building_list(
|
||||
"lot_buildings_industrial",
|
||||
lot_buildings_industrial);
|
||||
}
|
||||
if (it.world().has<PackerState>())
|
||||
it.world()
|
||||
.get_mut<PackerState>()
|
||||
->state++;
|
||||
});
|
||||
}
|
||||
|
||||
static inline Rect2 aabb2rect(const AABB &aabb)
|
||||
@@ -840,17 +859,17 @@ out_bad:
|
||||
}
|
||||
bool tmp_found = false;
|
||||
int office_count = 0;
|
||||
// FIXME use components and find instead of direct lookup
|
||||
AABB get_building_aabb(const String &key) const
|
||||
{
|
||||
const struct BuildingsData::building &b =
|
||||
bd()->get_building(key);
|
||||
const AABB &building_aabb = bd()->building_aabbs[b.id];
|
||||
return building_aabb;
|
||||
return bd()->get_scene_aabb(b.id);
|
||||
}
|
||||
// FIXME use components and find instead of direct lookup
|
||||
AABB get_building_type_aabb(const String &building) const
|
||||
{
|
||||
const AABB &building_aabb = bd()->building_aabbs[building];
|
||||
return building_aabb;
|
||||
return bd()->get_scene_aabb(building);
|
||||
}
|
||||
Transform get_building_transform(const String &key)
|
||||
{
|
||||
@@ -872,80 +891,99 @@ out_bad:
|
||||
void create()
|
||||
{
|
||||
int lot_count = 0;
|
||||
int i, j;
|
||||
Vector<flecs::entity> entities;
|
||||
Vector<flecs::entity> entities_all;
|
||||
Vector<Rect2> vrects;
|
||||
Vector<Transform> xforms;
|
||||
List<String> buildings;
|
||||
Vector<BuildingsData::building> vbuildings;
|
||||
bd()->get_building_keys_list(&buildings);
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot>()
|
||||
.write<LotBuildings>()
|
||||
.write<PreOccupied>()
|
||||
.read<PreOccupied>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, Lot &lot_) {
|
||||
assert(e.get<Lot>()->polygon.points.size() > 0);
|
||||
List<String> buildings;
|
||||
bd()->get_building_keys_list(&buildings);
|
||||
List<String>::Element *be = buildings.front();
|
||||
e.get_mut<Lot>()->polygon.update_aabb();
|
||||
if (e.has<PreOccupied>())
|
||||
return;
|
||||
while (be) {
|
||||
const String &key = be->get();
|
||||
const struct BuildingsData::building &b =
|
||||
bd()->get_building(key);
|
||||
if (key.begins_with("road__")) {
|
||||
be = be->next();
|
||||
continue;
|
||||
}
|
||||
if (allowed_building(b.id)) {
|
||||
be = be->next();
|
||||
continue;
|
||||
}
|
||||
AABB lot_aabb =
|
||||
e.get<Lot>()->polygon.aabb;
|
||||
Rect2 lot_rect = aabb2rect(
|
||||
e.get<Lot>()->polygon.aabb);
|
||||
Rect2 building_rect =
|
||||
get_rect_transformed(key);
|
||||
Transform xform =
|
||||
get_building_transform(key);
|
||||
Vector2 building_pos = Vector2(
|
||||
xform.origin.x, xform.origin.z);
|
||||
bool intersects = false;
|
||||
if (e.get<Lot>()->polygon.is_inside(
|
||||
building_rect))
|
||||
intersects = true;
|
||||
assert(e.get<Lot>()
|
||||
->polygon.points.size() >
|
||||
0);
|
||||
if (intersects) {
|
||||
assert(e.get<Lot>()
|
||||
->polygon.points
|
||||
.size() > 0);
|
||||
e.add<PreOccupied>();
|
||||
assert(e.get<Lot>()
|
||||
->polygon.points
|
||||
.size() > 0);
|
||||
LotBuildings &lb =
|
||||
e.ensure<LotBuildings>();
|
||||
lb.buildings.push_back(
|
||||
{ building_rect, key });
|
||||
Vector<Vector2> pt =
|
||||
get_polygon2(
|
||||
e.get<Lot>()
|
||||
->polygon
|
||||
.points);
|
||||
assert(pt.size() > 0);
|
||||
lb.polygons.push_back(pt);
|
||||
e.modified<LotBuildings>();
|
||||
}
|
||||
be = be->next();
|
||||
}
|
||||
if (!e.has<PreOccupied>())
|
||||
entities.push_back(e);
|
||||
});
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, Lot &lot_) {
|
||||
entities_all.push_back(e);
|
||||
});
|
||||
print_line("entities: " + itos(entities.size()));
|
||||
List<String>::Element *be = buildings.front();
|
||||
while (be) {
|
||||
const String &key = be->get();
|
||||
const struct BuildingsData::building &b =
|
||||
bd()->get_building(key);
|
||||
if (key.begins_with("road__")) {
|
||||
be = be->next();
|
||||
continue;
|
||||
}
|
||||
if (allowed_building(b.id)) {
|
||||
be = be->next();
|
||||
continue;
|
||||
}
|
||||
vbuildings.push_back(b);
|
||||
Rect2 building_rect = get_rect_transformed(b.key);
|
||||
vrects.push_back(building_rect);
|
||||
Transform xform = get_building_transform(b.key);
|
||||
xforms.push_back(xform);
|
||||
be = be->next();
|
||||
}
|
||||
print_line("buildings: " + itos(vbuildings.size()));
|
||||
for (i = 0; i < entities.size(); i++) {
|
||||
flecs::entity e = entities[i];
|
||||
print_line("Lot: " + itos(i) + " " + String(e.name()));
|
||||
assert(e.is_valid());
|
||||
assert(e.get<Lot>()->polygon.points.size() > 0);
|
||||
}
|
||||
// assert(false);
|
||||
for (i = 0; i < entities.size(); i++) {
|
||||
flecs::entity e = entities[i];
|
||||
print_line("Lot: " + itos(i) + " " + String(e.name()));
|
||||
Lot *lot_ = e.get_mut<Lot>();
|
||||
be = buildings.front();
|
||||
AABB lot_aabb = e.get<Lot>()->polygon.aabb;
|
||||
Rect2 lot_rect = aabb2rect(e.get<Lot>()->polygon.aabb);
|
||||
for (j = 0; j < vbuildings.size(); j++) {
|
||||
const struct BuildingsData::building &b =
|
||||
vbuildings[j];
|
||||
Rect2 building_rect = vrects[j];
|
||||
Transform xform = xforms[j];
|
||||
Vector2 building_pos =
|
||||
Vector2(xform.origin.x, xform.origin.z);
|
||||
bool intersects = false;
|
||||
if (e.get<Lot>()->polygon.is_inside(
|
||||
building_rect))
|
||||
intersects = true;
|
||||
if (intersects) {
|
||||
e.add<PreOccupied>();
|
||||
LotBuildings &lb =
|
||||
e.ensure<LotBuildings>();
|
||||
lb.buildings.push_back(
|
||||
{ building_rect, b.key });
|
||||
Vector<Vector2> pt = get_polygon2(
|
||||
e.get<Lot>()->polygon.points);
|
||||
assert(pt.size() > 0);
|
||||
lb.polygons.push_back(pt);
|
||||
e.modified<LotBuildings>();
|
||||
}
|
||||
}
|
||||
}
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot, LotBuildings>()
|
||||
.with<PreOccupied>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, Lot &lot, LotBuildings &lb) {
|
||||
int i;
|
||||
for (i = 0; i < lb.buildings.size(); i++) {
|
||||
const Pair<Rect2, String> &mp =
|
||||
lb.buildings[i];
|
||||
@@ -956,6 +994,9 @@ out_bad:
|
||||
get_rect_transformed(key);
|
||||
Rect2 lot_rect =
|
||||
aabb2rect(lot.polygon.aabb);
|
||||
assert(bd()->has_scene(
|
||||
"office-exterior"));
|
||||
print_line("building type: " + b.id);
|
||||
if (b.id == "office-exterior") {
|
||||
print_line("id: " + b.id);
|
||||
print_line("xform: " +
|
||||
@@ -972,6 +1013,19 @@ out_bad:
|
||||
}
|
||||
}
|
||||
});
|
||||
for (i = 0; i < entities.size(); i++) {
|
||||
flecs::entity e = entities[i];
|
||||
if (e.has<PreOccupied>())
|
||||
continue;
|
||||
if ((lot_count % 5) == 0)
|
||||
e.add<Industrial>();
|
||||
else if (lot_count % 3 == 0)
|
||||
e.add<Commercial>();
|
||||
else
|
||||
e.add<Residental>();
|
||||
lot_count++;
|
||||
}
|
||||
#if 0
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot>()
|
||||
@@ -1080,14 +1134,12 @@ out_bad:
|
||||
e.add<Residental>();
|
||||
lot_count++;
|
||||
});
|
||||
#endif
|
||||
assert(tmp_found);
|
||||
print_line("office_count: " + itos(office_count));
|
||||
// assert(office_count > 1);
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot>()
|
||||
.build()
|
||||
.each([&](flecs::entity e, Lot &lot) { add_lot(e); });
|
||||
for (i = 0; i < entities_all.size(); i++)
|
||||
add_lot(entities_all[i]);
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.query_builder<Lot>()
|
||||
@@ -1292,31 +1344,42 @@ out_bad:
|
||||
return lb->polygons;
|
||||
}
|
||||
};
|
||||
LotPacker *LotPacker::singleton = nullptr;
|
||||
|
||||
void Lot::pack()
|
||||
{
|
||||
LotPacker::get_singleton()->create();
|
||||
LotPacker::get_singleton()->pack_lots();
|
||||
BaseData::get_singleton()->get().get_mut<LotPacker>()->create();
|
||||
BaseData::get_singleton()->get().get_mut<LotPacker>()->pack_lots();
|
||||
BaseData::get_singleton()->get().modified<LotPacker>();
|
||||
}
|
||||
|
||||
void Lot::get_lot_data(flecs::entity e, List<Pair<AABB, String> > *lot_data)
|
||||
{
|
||||
LotPacker::get_singleton()->get_lot_data(e, lot_data);
|
||||
BaseData::get_singleton()->get().get_mut<LotPacker>()->get_lot_data(
|
||||
e, lot_data);
|
||||
}
|
||||
|
||||
void Lot::get_lot_rotations(flecs::entity e, List<Transform> *lot_xform)
|
||||
{
|
||||
LotPacker::get_singleton()->get_lot_rotations(e, lot_xform);
|
||||
BaseData::get_singleton()->get().get_mut<LotPacker>()->get_lot_rotations(
|
||||
e, lot_xform);
|
||||
}
|
||||
|
||||
void Lot::get_lot_buildings(flecs::entity e,
|
||||
Vector<Pair<Rect2, String> > *lot_buildings)
|
||||
{
|
||||
LotPacker::get_singleton()->get_lot_buildings(e, lot_buildings);
|
||||
BaseData::get_singleton()->get().get_mut<LotPacker>()->get_lot_buildings(
|
||||
e, lot_buildings);
|
||||
}
|
||||
|
||||
Vector<Vector<Vector2> > Lot::get_lot_polygons(flecs::entity e)
|
||||
{
|
||||
return LotPacker::get_singleton()->get_lot_polygons(e);
|
||||
return BaseData::get_singleton()
|
||||
->get()
|
||||
.get_mut<LotPacker>()
|
||||
->get_lot_polygons(e);
|
||||
}
|
||||
|
||||
void Lot::import_packer(flecs::world &ecs)
|
||||
{
|
||||
ecs.import <LotPacker>();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ struct Lot {
|
||||
get_lot_buildings(flecs::entity e,
|
||||
Vector<Pair<Rect2, String> > *lot_buildings);
|
||||
static Vector<Vector<Vector2> > get_lot_polygons(flecs::entity e);
|
||||
static void import_packer(flecs::world &ecs);
|
||||
};
|
||||
|
||||
#endif // ROAD_LOT_H_
|
||||
@@ -88,9 +88,10 @@ struct RoadLinesProcessing {
|
||||
int debug_flags;
|
||||
DebugGeo *dbg;
|
||||
static ConfigFile config;
|
||||
RoadLinesProcessing()
|
||||
RoadLinesProcessing(flecs::world &ecs)
|
||||
: dbg(nullptr)
|
||||
{
|
||||
ecs.module<RoadLinesProcessing>();
|
||||
Error err = config.load("res://config/stream.conf");
|
||||
assert(err == OK);
|
||||
}
|
||||
@@ -158,7 +159,7 @@ struct RoadLinesProcessing {
|
||||
}
|
||||
bd()->create_building(b);
|
||||
if (!bd()->has_scene(b.id))
|
||||
bd()->create_scene_data(b.id, b.key);
|
||||
return;
|
||||
else
|
||||
bd()->add_scene_item(b.id, b.key);
|
||||
print_line("created building: " + b.key + " " + b.id);
|
||||
@@ -919,7 +920,10 @@ out2:;
|
||||
void find_closed_contours()
|
||||
{
|
||||
int i, j;
|
||||
Contours *contours = Contours::get_singleton();
|
||||
print_line("find_closed_contours");
|
||||
assert(this);
|
||||
Contours *contours =
|
||||
BaseData::get_singleton()->get().get_mut<Contours>();
|
||||
// RoadLinesProcessing *r = BaseData::get_singleton() ->get() .get_mut<RoadLinesProcessing>();
|
||||
RoadLinesProcessing *r = this;
|
||||
if (r->nodes.size() == 0)
|
||||
@@ -985,7 +989,7 @@ out2:;
|
||||
}
|
||||
if (finished) {
|
||||
int k;
|
||||
print_line("complete contour");
|
||||
// print_line("complete contour");
|
||||
std::vector<struct wedge *> wedge_contour;
|
||||
Vector<Vector2> polygon;
|
||||
for (k = 0; k < (int)contour.size(); k++) {
|
||||
@@ -993,8 +997,8 @@ out2:;
|
||||
wedges_ref[contour[k]];
|
||||
wedge_contour.push_back(
|
||||
&wedges[wr.first][wr.second]);
|
||||
print_line(itos(k) + ": " +
|
||||
itos(contour[k]));
|
||||
// print_line(itos(k) + ": " +
|
||||
// itos(contour[k]));
|
||||
Vector3 p1 =
|
||||
wedges[wr.first][wr.second].p[0];
|
||||
Vector3 p2 =
|
||||
@@ -1007,9 +1011,8 @@ out2:;
|
||||
used.push_back(contour[k]);
|
||||
}
|
||||
if (Geometry::is_polygon_clockwise(polygon))
|
||||
contours->get_singleton()
|
||||
->wedge_contours.push_back(
|
||||
wedge_contour);
|
||||
contours->wedge_contours.push_back(
|
||||
wedge_contour);
|
||||
contour.clear();
|
||||
contour_count++;
|
||||
} else
|
||||
@@ -1018,8 +1021,6 @@ out2:;
|
||||
if (base >= (int)wedges_ref.size())
|
||||
break;
|
||||
}
|
||||
contours->build();
|
||||
contours->debug();
|
||||
}
|
||||
~RoadLinesProcessing()
|
||||
{
|
||||
@@ -1032,27 +1033,10 @@ out2:;
|
||||
{
|
||||
return debug_flags;
|
||||
}
|
||||
void road_setup()
|
||||
void road_setup2()
|
||||
{
|
||||
int i, j;
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
std::vector<Vector3> road_lines_nodes;
|
||||
std::unordered_map<uint32_t, std::vector<Vector3> >
|
||||
road_lines_nodes_hash;
|
||||
road_lines_nodes.clear();
|
||||
road_lines_nodes_hash.clear();
|
||||
rld->update_line_edges();
|
||||
test_lines();
|
||||
calculate_lot_depths();
|
||||
rld->set_debug_flags(debug_flags);
|
||||
rld->process_lines(road_lines_nodes_hash, road_lines_nodes);
|
||||
create_nodes(road_lines_nodes);
|
||||
create_edges();
|
||||
optimize_nodes(16.0f);
|
||||
sort_neighbors();
|
||||
wedges.clear();
|
||||
build_wedges(wedges);
|
||||
find_closed_contours();
|
||||
// update_lot_depths();
|
||||
ImmediateGeometry *d = rld->get_debug_node();
|
||||
d->clear();
|
||||
@@ -1114,7 +1098,6 @@ out2:;
|
||||
}
|
||||
d->end();
|
||||
}
|
||||
create_structures();
|
||||
print_line("ROAD SETUP DONE");
|
||||
}
|
||||
};
|
||||
@@ -1703,7 +1686,9 @@ public:
|
||||
out_surfaces[h], 0.0f);
|
||||
} else if (k == params.nlanes + 1 &&
|
||||
mside1.lot > 0) { /* lot */
|
||||
if (!Contours::get_singleton()
|
||||
if (!BaseData::get_singleton()
|
||||
->get()
|
||||
.get<Contours>()
|
||||
->is_in_closed_contour(
|
||||
&wedge))
|
||||
build_split_segment(
|
||||
@@ -1779,7 +1764,9 @@ public:
|
||||
"m2: " +
|
||||
String::num(
|
||||
mside2.lot_depth_eff));
|
||||
if (!Contours::get_singleton()
|
||||
if (!BaseData::get_singleton()
|
||||
->get()
|
||||
.get<Contours>()
|
||||
->is_in_closed_contour(
|
||||
&wedge))
|
||||
build_split_segment(
|
||||
@@ -1864,25 +1851,51 @@ public:
|
||||
nodes_mi.push_back(mi);
|
||||
}
|
||||
}
|
||||
RoadMeshProcessing()
|
||||
RoadMeshProcessing(flecs::world &ecs)
|
||||
: road_mgroup(nullptr)
|
||||
{
|
||||
BaseData::get_singleton()->get().ensure<RoadLinesProcessing>();
|
||||
ecs.module<RoadMeshProcessing>();
|
||||
ecs.import <RoadLinesProcessing>();
|
||||
}
|
||||
};
|
||||
|
||||
void RoadProcessing::road_setup(Node *target, int debug_flags)
|
||||
{
|
||||
BaseData::get_singleton()->get().ensure<RoadLinesProcessing>();
|
||||
BaseData::get_singleton()->get().ensure<RoadMeshProcessing>();
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
int i, j;
|
||||
RoadLinesProcessing *r =
|
||||
BaseData::get_singleton()->get().get_mut<RoadLinesProcessing>();
|
||||
r->set_debug_flags(debug_flags);
|
||||
r->road_setup();
|
||||
std::vector<Vector3> road_lines_nodes;
|
||||
std::unordered_map<uint32_t, std::vector<Vector3> >
|
||||
road_lines_nodes_hash;
|
||||
road_lines_nodes.clear();
|
||||
road_lines_nodes_hash.clear();
|
||||
rld->update_line_edges();
|
||||
r->test_lines();
|
||||
r->calculate_lot_depths();
|
||||
rld->set_debug_flags(debug_flags);
|
||||
rld->process_lines(road_lines_nodes_hash, road_lines_nodes);
|
||||
r->create_nodes(road_lines_nodes);
|
||||
r->create_edges();
|
||||
r->optimize_nodes(16.0f);
|
||||
r->sort_neighbors();
|
||||
r->wedges.clear();
|
||||
r->build_wedges(r->wedges);
|
||||
print_line("find_closed_contours");
|
||||
r->find_closed_contours();
|
||||
Contours *contours =
|
||||
BaseData::get_singleton()->get().get_mut<Contours>();
|
||||
contours->build();
|
||||
Lot::pack();
|
||||
contours->debug();
|
||||
BaseData::get_singleton()->get().modified<Contours>();
|
||||
r->create_structures();
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.get_mut<RoadMeshProcessing>()
|
||||
->create_road_meshes(target);
|
||||
r->road_setup2();
|
||||
}
|
||||
|
||||
void RoadProcessing::remove_road_meshes(Node *target)
|
||||
@@ -1900,7 +1913,6 @@ void RoadProcessing::load_data()
|
||||
ConfigFile config;
|
||||
Error result = config.load("res://config/stream.conf");
|
||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||
BaseData::get_singleton()->get().ensure<RoadMeshProcessing>();
|
||||
RoadMeshProcessing *rmp =
|
||||
BaseData::get_singleton()->get().get_mut<RoadMeshProcessing>();
|
||||
assert(rmp);
|
||||
@@ -2025,3 +2037,15 @@ void RoadProcessing::cleanup()
|
||||
BaseData::get_singleton()->get().remove<RoadLinesProcessing>();
|
||||
BaseData::get_singleton()->get().remove<RoadMeshProcessing>();
|
||||
}
|
||||
|
||||
RoadProcessing::RoadProcessing(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<RoadProcessing>();
|
||||
ecs.import <Contours>();
|
||||
ecs.import <RoadLinesProcessing>();
|
||||
ecs.import <RoadMeshProcessing>();
|
||||
}
|
||||
|
||||
RoadProcessing::~RoadProcessing()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifndef ROAD_LINES_PROCESSING_H_
|
||||
#define ROAD_LINES_PROCESSSING_H_
|
||||
#include <flecs.h>
|
||||
class Node;
|
||||
class ImmediateGeometry;
|
||||
class RoadProcessing {
|
||||
@@ -8,5 +9,7 @@ public:
|
||||
static void remove_road_meshes(Node *target);
|
||||
static void load_data();
|
||||
static void cleanup();
|
||||
RoadProcessing(flecs::world &ecs);
|
||||
virtual ~RoadProcessing();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,7 @@ void StreamWorld::create_tilemap()
|
||||
|
||||
void StreamWorld::update_view()
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
ERR_FAIL_COND_MSG(!initialized,
|
||||
"The Stream object is incorrectly initialized");
|
||||
if (!viewer || !terrain) {
|
||||
@@ -84,6 +84,12 @@ void StreamWorld::update_view()
|
||||
ERR_FAIL_COND_MSG(!t, "VoxelLodTerrain was not found");
|
||||
viewer = v;
|
||||
terrain = t;
|
||||
assert(terrain);
|
||||
assert(viewer);
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.set<StreamWorld::components::WorldData>(
|
||||
{ viewer, terrain });
|
||||
viewer->connect("tree_exiting", this, "viewer_dead");
|
||||
terrain->connect("tree_exiting", this, "terrain_dead");
|
||||
current_x = world_extent + 1;
|
||||
@@ -218,7 +224,7 @@ void StreamWorld::unload_building(const String &key)
|
||||
void StreamWorld::update_items()
|
||||
{
|
||||
List<String> keys;
|
||||
data()->get_scene_keys_list(&keys);
|
||||
BuildingsData::get_scene_keys_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
const String &key = e->get();
|
||||
@@ -260,6 +266,7 @@ void StreamWorld::remove_building(const String &key)
|
||||
|
||||
VoxelLodTerrain *StreamWorld::get_terrain()
|
||||
{
|
||||
assert(terrain);
|
||||
return terrain;
|
||||
}
|
||||
|
||||
@@ -316,7 +323,7 @@ void StreamWorld::run_command(const String &command,
|
||||
String new_type = args[1];
|
||||
Dictionary buildings_data =
|
||||
config.get_value("buildings", "building_data");
|
||||
if (!data()->building_data.has(new_type)) {
|
||||
if (!data()->has_scene(new_type)) {
|
||||
print_error("unknown building type: " + new_type);
|
||||
return;
|
||||
}
|
||||
@@ -403,7 +410,7 @@ void StreamWorld::run_command(const String &command,
|
||||
create_tilemap();
|
||||
#endif
|
||||
update_view();
|
||||
data()->scene_update();
|
||||
BuildingsData::scene_update();
|
||||
update_items();
|
||||
#if 0
|
||||
data()->for_each_building(
|
||||
@@ -453,7 +460,17 @@ void StreamWorld::_notification(int which)
|
||||
if (current_scene)
|
||||
current_scene = get_tree()->get_root();
|
||||
}
|
||||
#if 0
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.add<StreamWorld::components::Initialized>();
|
||||
#endif
|
||||
ERR_FAIL_COND_MSG(!current_scene, "No current scene");
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
break;
|
||||
set_process(true);
|
||||
#if 0
|
||||
BaseData::get_singleton()->get().defer_suspend();
|
||||
RoadProcessing::road_setup(this, 0);
|
||||
#if 0
|
||||
data()->for_each_building(
|
||||
@@ -471,6 +488,7 @@ void StreamWorld::_notification(int which)
|
||||
#if 0
|
||||
create_tilemap();
|
||||
#endif
|
||||
BaseData::get_singleton()->get().defer_resume();
|
||||
set_process(true);
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
break;
|
||||
@@ -480,12 +498,14 @@ void StreamWorld::_notification(int which)
|
||||
update_view();
|
||||
assert(terrain);
|
||||
assert(viewer);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
frame_count = 0;
|
||||
break;
|
||||
case NOTIFICATION_PROCESS: {
|
||||
#if 0
|
||||
if (frame_count % 60 == 0) {
|
||||
float fmon = Performance::get_singleton()->get_monitor(
|
||||
Performance::RENDER_DRAW_CALLS_IN_FRAME);
|
||||
@@ -497,6 +517,12 @@ void StreamWorld::_notification(int which)
|
||||
update_view();
|
||||
data()->scene_update();
|
||||
update_items();
|
||||
#endif
|
||||
if (road_setup_needed && !road_setup_complete) {
|
||||
road_setup();
|
||||
road_setup_needed = false;
|
||||
road_setup_complete = true;
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
@@ -525,14 +551,30 @@ StreamWorld::StreamWorld()
|
||||
, view_distance(0)
|
||||
, initialized(false)
|
||||
, frame_count(0)
|
||||
, road_setup_needed(false)
|
||||
, road_setup_complete(false)
|
||||
, count_shit(0)
|
||||
{
|
||||
BaseData::get_singleton()->get().component<BuildingsData>();
|
||||
BaseData::get_singleton()->get().import <BuildingsData>();
|
||||
BaseData::get_singleton()->get().import <RoadProcessing>();
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.component<StreamWorld::components::RoadSetupDone>();
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.component<StreamWorld::components::RoadSetupNeeded>();
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.component<StreamWorld::components::Initialized>();
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.component<StreamWorld::components::WorldData>();
|
||||
Error result = config.load("res://config/stream.conf");
|
||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||
BaseData::get_singleton()->get().ensure<BuildingsData>();
|
||||
RoadProcessing::load_data();
|
||||
world_extent = config.get_value("world", "world_extent");
|
||||
tile_size = config.get_value("world", "tile_size");
|
||||
view_distance = config.get_value("world", "view_distance");
|
||||
ERR_FAIL_COND_MSG(tile_size <= 0 || world_extent <= 0 ||
|
||||
world_extent <= tile_size,
|
||||
"Failed to configure world");
|
||||
@@ -548,11 +590,40 @@ StreamWorld::StreamWorld()
|
||||
map_it++;
|
||||
}
|
||||
#endif
|
||||
view_distance = config.get_value("world", "view_distance");
|
||||
BaseData::get_singleton()->get().import <NPC>();
|
||||
flecs::entity npcctrl = BaseData::get_singleton()->get().entity();
|
||||
npcctrl.set<NPC::NPCControl>({ NPC::NPCControl::CMD_PRESIM });
|
||||
initialized = true;
|
||||
flecs::log::set_level(-3);
|
||||
BaseData::get_singleton()
|
||||
->get()
|
||||
.system("WaitForUpdate")
|
||||
.kind(flecs::OnUpdate)
|
||||
.run([&](flecs::iter &it) {
|
||||
if (road_setup_complete)
|
||||
return;
|
||||
if (!road_setup_needed && !road_setup_complete)
|
||||
road_setup_needed = true;
|
||||
#if 0
|
||||
if (it.world()
|
||||
.has<StreamWorld::components::RoadSetupDone>())
|
||||
return;
|
||||
if (it.world()
|
||||
.has<StreamWorld::components::Initialized>() &&
|
||||
!it.world()
|
||||
.has<StreamWorld::components::
|
||||
RoadSetupNeeded>()) {
|
||||
road_setup_needed = true;
|
||||
it.world()
|
||||
.add<StreamWorld::components::
|
||||
RoadSetupNeeded>();
|
||||
} else if (it.world()
|
||||
.has<BuildingsData::CScenesLoaded>())
|
||||
it.world()
|
||||
.add<StreamWorld::components::
|
||||
Initialized>();
|
||||
#endif
|
||||
});
|
||||
}
|
||||
void StreamWorld::cleanup()
|
||||
{
|
||||
@@ -592,3 +663,16 @@ void StreamWorld::undo()
|
||||
update_view();
|
||||
update_items();
|
||||
}
|
||||
|
||||
void StreamWorld::road_setup()
|
||||
{
|
||||
assert(count_shit == 0);
|
||||
RoadProcessing::road_setup(this, 0);
|
||||
update_view();
|
||||
data()->scene_update();
|
||||
update_items();
|
||||
update_view();
|
||||
count_shit++;
|
||||
assert(terrain);
|
||||
assert(viewer);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ private:
|
||||
bool initialized;
|
||||
int current_x, current_z;
|
||||
int frame_count;
|
||||
bool road_setup_needed;
|
||||
bool road_setup_complete;
|
||||
int count_shit;
|
||||
void _notification(int which);
|
||||
// void create_tilemap();
|
||||
void update_view();
|
||||
@@ -51,10 +54,20 @@ private:
|
||||
void remove_generated_stuff();
|
||||
void place_zebras();
|
||||
void undo();
|
||||
void road_setup();
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
struct components {
|
||||
struct Initialized {};
|
||||
struct WorldData {
|
||||
VoxelViewer *viewer;
|
||||
VoxelLodTerrain *terrain;
|
||||
};
|
||||
struct RoadSetupNeeded {};
|
||||
struct RoadSetupDone {};
|
||||
};
|
||||
VoxelLodTerrain *get_terrain();
|
||||
void run_command(const String &command, const Vector<Variant> &args);
|
||||
StreamWorld();
|
||||
|
||||
@@ -34,8 +34,14 @@ void TerrainEditor::exit()
|
||||
|
||||
void TerrainEditor::update(float delta)
|
||||
{
|
||||
if (!active)
|
||||
activate();
|
||||
if (!active) {
|
||||
if (BaseData::get_singleton()
|
||||
->get()
|
||||
.has<StreamWorld::components::WorldData>())
|
||||
activate();
|
||||
else
|
||||
return;
|
||||
}
|
||||
if (!cursor_enabled && get_camera_mode() == 3) {
|
||||
cursor_enabled = true;
|
||||
get_as_node<Spatial>(cursor_name)->show();
|
||||
@@ -382,7 +388,7 @@ end:;
|
||||
"building elevation: " +
|
||||
String::num(imgmapper->get_height_full(
|
||||
b.xform.origin)));
|
||||
AABB aabb = bd()->building_aabbs[b.id];
|
||||
AABB aabb = bd()->get_scene_aabb(b.id);
|
||||
print_line("building AABB: " +
|
||||
(aabb.operator String()));
|
||||
float max_elevation_c = -Math_INF,
|
||||
|
||||
@@ -614,6 +614,7 @@ void MainTabs::_notification(int which)
|
||||
std::vector<Variant> args_data = {
|
||||
items[i].header
|
||||
};
|
||||
assert(items[i].header.length() > 0);
|
||||
ui_field::ui_field_builder(this, tab,
|
||||
"l_p{v{}}",
|
||||
args_data.data(),
|
||||
|
||||
@@ -40,9 +40,10 @@ void ui_field::ui_field_builder(Node *owner, Node *parent, const String format,
|
||||
.get<WorldEditor::components::buildings_editor_node>()
|
||||
->node;
|
||||
assert(owner->is_inside_tree());
|
||||
for (i = 0; i < format.length(); i++) {
|
||||
const char *fmt = format.ascii().ptr();
|
||||
int c = fmt[i];
|
||||
CharString cformat = format.ascii();
|
||||
for (i = 0; i < format.ascii().length(); i++) {
|
||||
assert(i < cformat.length());
|
||||
int c = (int)cformat.ptr()[i];
|
||||
// printf("character: %c : argp: %d\n", (char)c, argp);
|
||||
switch (c) {
|
||||
case '{':
|
||||
|
||||
Reference in New Issue
Block a user