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
|
EDITOR2_PLATFORM=x11
|
||||||
DEMO_PLATFORMS=x11 x11es
|
DEMO_PLATFORMS=x11 x11es
|
||||||
EDITOR = src/godot/bin/godot.$(EDITOR_PLATFORM).opt.tools.$(ARCH)
|
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 = 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-clean export-linux-demo export-windows-demo \
|
||||||
export-binaries patch tests import-vrm export-buildings
|
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
|
SCONS_EXTRA=-j16
|
||||||
define build_godot
|
define build_godot
|
||||||
$(4): $(5)
|
$(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-main: $(GODOT_MAIN_TARGETS) godot-editor-main godot-server-main
|
||||||
godot-server-main: $(SERVER)
|
godot-server-main: $(SERVER)
|
||||||
godot-editor-main: $(EDITOR) $(EDITOR2)
|
godot-editor-main: $(EDITOR) $(EDITOR2)
|
||||||
|
godot-editor-debug: $(EDITOR_DBG) $(EDITOR2_DBG)
|
||||||
#$(SERVER): patch
|
#$(SERVER): patch
|
||||||
# cd src/godot; \
|
# cd src/godot; \
|
||||||
# scons platform=server arch=$(ARCH) target=release_debug tools=yes custom_modules=../modules -j16
|
# 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,server,release_debug,yes,$(SERVER),patch))
|
||||||
$(eval $(call build_godot,x11es,release_debug,yes,$(EDITOR),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,release_debug,yes,$(EDITOR2),patch))
|
||||||
|
$(eval $(call build_godot,x11,debug,yes,$(EDITOR2_DBG),patch))
|
||||||
patch: ./src/godot/scene/animation/skeleton_ik.cpp
|
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
|
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
|
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 "base_data.h"
|
||||||
#include "buildings_data.h"
|
#include "buildings_data.h"
|
||||||
|
|
||||||
static ConfigFile config;
|
ConfigFile BuildingsData::config;
|
||||||
static ConfigFile custom_layouts;
|
|
||||||
struct scene_data {
|
|
||||||
Ref<PackedScene> packed_scene;
|
|
||||||
String path;
|
|
||||||
Ref<ResourceInteractiveLoader> loader;
|
|
||||||
};
|
|
||||||
|
|
||||||
static flecs::world &ecs()
|
static flecs::world &ecs()
|
||||||
{
|
{
|
||||||
@@ -37,250 +31,12 @@ static flecs::entity lookup(const char *key)
|
|||||||
{
|
{
|
||||||
return ecs().lookup(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()
|
void BuildingsData::build_building_aabbs()
|
||||||
{
|
{
|
||||||
building_aabbs.clear();
|
// building_aabbs.clear();
|
||||||
List<String> keys;
|
// List<String> keys;
|
||||||
building_data.get_key_list(&keys);
|
// building_data.get_key_list(&keys);
|
||||||
List<String>::Element *e = keys.front();
|
// 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::update_building_transform(const String &key,
|
void BuildingsData::update_building_transform(const String &key,
|
||||||
@@ -301,7 +57,7 @@ bool BuildingsData::has_building(const String &key)
|
|||||||
return e.is_valid();
|
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;
|
float dst = Math_INF;
|
||||||
String rkey;
|
String rkey;
|
||||||
@@ -318,8 +74,7 @@ String BuildingsData::get_closest_building(const Transform &xform) const
|
|||||||
});
|
});
|
||||||
return rkey;
|
return rkey;
|
||||||
}
|
}
|
||||||
flecs::entity
|
flecs::entity BuildingsData::get_closest_building_entity(const Transform &xform)
|
||||||
BuildingsData::get_closest_building_entity(const Transform &xform) const
|
|
||||||
{
|
{
|
||||||
float dst = Math_INF;
|
float dst = Math_INF;
|
||||||
String rkey;
|
String rkey;
|
||||||
@@ -500,6 +255,7 @@ void BuildingsData::load_data()
|
|||||||
assert(ecs().has<CBuildingStats>());
|
assert(ecs().has<CBuildingStats>());
|
||||||
Error result = config.load("res://config/stream.conf");
|
Error result = config.load("res://config/stream.conf");
|
||||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
|
#if 0
|
||||||
Dictionary buildings_data =
|
Dictionary buildings_data =
|
||||||
config.get_value("buildings", "building_data");
|
config.get_value("buildings", "building_data");
|
||||||
List<Variant> keys;
|
List<Variant> keys;
|
||||||
@@ -507,7 +263,23 @@ void BuildingsData::load_data()
|
|||||||
List<Variant>::Element *e = keys.front();
|
List<Variant>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
String key = e->get();
|
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 = e->next();
|
||||||
}
|
}
|
||||||
e = keys.front();
|
e = keys.front();
|
||||||
@@ -516,12 +288,14 @@ void BuildingsData::load_data()
|
|||||||
// print_line(key + ": " + buildings_data[key]);
|
// print_line(key + ": " + buildings_data[key]);
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
String buildings_path = config.get_value("buildings", "buildings_path");
|
String buildings_path = config.get_value("buildings", "buildings_path");
|
||||||
read_buildings_json(buildings_path);
|
read_buildings_json(buildings_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::checkpoint()
|
void BuildingsData::checkpoint()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
struct checkpoint_data cp;
|
struct checkpoint_data cp;
|
||||||
cp.building_data = building_data;
|
cp.building_data = building_data;
|
||||||
cp.buildings.clear();
|
cp.buildings.clear();
|
||||||
@@ -531,9 +305,11 @@ void BuildingsData::checkpoint()
|
|||||||
undo_log.push_back(cp);
|
undo_log.push_back(cp);
|
||||||
while ((int)undo_log.size() > undo_log_size)
|
while ((int)undo_log.size() > undo_log_size)
|
||||||
undo_log.erase(undo_log.begin());
|
undo_log.erase(undo_log.begin());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void BuildingsData::undo()
|
void BuildingsData::undo()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
int i;
|
int i;
|
||||||
struct checkpoint_data cp = *undo_log.end();
|
struct checkpoint_data cp = *undo_log.end();
|
||||||
building_data = cp.building_data;
|
building_data = cp.building_data;
|
||||||
@@ -545,98 +321,44 @@ void BuildingsData::undo()
|
|||||||
flecs::entity e = ecs().entity(ename.ascii().ptr());
|
flecs::entity e = ecs().entity(ename.ascii().ptr());
|
||||||
e.set<CBuildingData>({ cp.buildings[i] });
|
e.set<CBuildingData>({ cp.buildings[i] });
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::fill_door_locations()
|
void BuildingsData::get_scene_keys_list(List<String> *keys)
|
||||||
{
|
|
||||||
/*
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
ecs().each([keys](flecs::entity e, const CSceneData &d) {
|
ecs().each([keys](flecs::entity e, const CSceneData &d) {
|
||||||
keys->push_back(String(e.name()));
|
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());
|
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 =
|
flecs::query_builder<const CBuildingData> qb =
|
||||||
ecs().query_builder<const CBuildingData>();
|
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());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
assert(e.is_valid());
|
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>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
String ename = "bi:" + bkey;
|
String ename = "bi:" + bkey;
|
||||||
@@ -697,54 +424,46 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
|||||||
if (ce.is_valid())
|
if (ce.is_valid())
|
||||||
ce.destruct();
|
ce.destruct();
|
||||||
ce = ecs().entity(ename.ascii().ptr()).child_of(e);
|
ce = ecs().entity(ename.ascii().ptr()).child_of(e);
|
||||||
|
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 });
|
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||||
// print_line("child name: " + String(ce.name()));
|
// print_line("child name: " + String(ce.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key)
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
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())
|
if (!e.is_valid())
|
||||||
return Ref<PackedScene>();
|
return Ref<PackedScene>();
|
||||||
if (!e.get<CSceneData>())
|
if (!e.get<CSceneData>())
|
||||||
return Ref<PackedScene>();
|
return Ref<PackedScene>();
|
||||||
|
if (!e.get<CScenePack>())
|
||||||
|
return Ref<PackedScene>();
|
||||||
assert(e.is_valid());
|
assert(e.is_valid());
|
||||||
const CSceneData *d = e.get<CSceneData>();
|
const CScenePack *d = e.get<CScenePack>();
|
||||||
assert(d);
|
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());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
if (!e.is_valid())
|
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));
|
// print_line("scene_get_item_count: " + itos(result));
|
||||||
return 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;
|
List<String> ret;
|
||||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
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);
|
||||||
assert(bi->key == bkey);
|
assert(bi->key == bkey);
|
||||||
bi->node = node;
|
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());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
assert(e.is_valid());
|
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());
|
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||||
return ce.is_valid();
|
return ce.is_valid();
|
||||||
}
|
}
|
||||||
Node *BuildingsData::get_scene_item_node(const String &key,
|
Node *BuildingsData::get_scene_item_node(const String &key, const String &bkey)
|
||||||
const String &bkey) const
|
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
assert(e.is_valid());
|
assert(e.is_valid());
|
||||||
@@ -823,6 +542,8 @@ Node *BuildingsData::get_scene_item_node(const String &key,
|
|||||||
assert(d);
|
assert(d);
|
||||||
String ename = "bi:" + bkey;
|
String ename = "bi:" + bkey;
|
||||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||||
|
if (!ce.is_valid()) /* no instance */
|
||||||
|
return nullptr;
|
||||||
assert(ce.is_valid());
|
assert(ce.is_valid());
|
||||||
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
|
CBuildingInstance *bi = ce.get_mut<CBuildingInstance>();
|
||||||
assert(bi);
|
assert(bi);
|
||||||
@@ -836,7 +557,7 @@ void BuildingsData::save_buildings()
|
|||||||
save_buildings_json(buildings_path);
|
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 =
|
flecs::query_builder<const CBuildingInstance> qb =
|
||||||
ecs().query_builder<const CBuildingInstance>();
|
ecs().query_builder<const CBuildingInstance>();
|
||||||
@@ -851,29 +572,6 @@ Node *BuildingsData::item_nodes_get_node(const String &key) const
|
|||||||
return nullptr;
|
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()
|
void BuildingsData::scene_update()
|
||||||
{
|
{
|
||||||
List<String> keys;
|
List<String> keys;
|
||||||
@@ -885,12 +583,11 @@ void BuildingsData::scene_update()
|
|||||||
e = e->next();
|
e = e->next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scene_loader_poll(key);
|
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BuildingsData::get_building_count() const
|
int BuildingsData::get_building_count()
|
||||||
{
|
{
|
||||||
flecs::query<const CBuildingData> q =
|
flecs::query<const CBuildingData> q =
|
||||||
ecs().query<const CBuildingData>();
|
ecs().query<const CBuildingData>();
|
||||||
@@ -906,20 +603,24 @@ int BuildingsData::get_building_count() const
|
|||||||
return result;
|
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 &
|
struct BuildingsData::building &
|
||||||
BuildingsData::get_building(const String &building_key)
|
BuildingsData::get_building(const String &building_key)
|
||||||
{
|
{
|
||||||
String ename = "base:" + building_key;
|
String ename = "base:" + building_key;
|
||||||
flecs::entity e = lookup(ename);
|
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());
|
assert(e.is_valid());
|
||||||
return e.get_mut<CBuildingData>()->building;
|
return e.get_mut<CBuildingData>()->building;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,14 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <core/reference.h>
|
#include <core/reference.h>
|
||||||
|
#include <scene/resources/packed_scene.h>
|
||||||
|
#include <core/io/config_file.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
class PackedScene;
|
class PackedScene;
|
||||||
class ResourceInteractiveLoader;
|
class ResourceInteractiveLoader;
|
||||||
class BuildingsData {
|
class BuildingsData {
|
||||||
|
static ConfigFile config;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Per-building information */
|
/* Per-building information */
|
||||||
struct building {
|
struct building {
|
||||||
@@ -23,6 +27,15 @@ public:
|
|||||||
Dictionary to_dict() const;
|
Dictionary to_dict() const;
|
||||||
String line_name;
|
String line_name;
|
||||||
};
|
};
|
||||||
|
struct scene_data {
|
||||||
|
String key;
|
||||||
|
String path;
|
||||||
|
};
|
||||||
|
struct scene_pack {
|
||||||
|
Ref<PackedScene> packed_scene;
|
||||||
|
Ref<ResourceInteractiveLoader> loader;
|
||||||
|
};
|
||||||
|
|
||||||
Set<String> pending_scene;
|
Set<String> pending_scene;
|
||||||
/* Scene objects data */
|
/* Scene objects data */
|
||||||
//private:
|
//private:
|
||||||
@@ -31,6 +44,9 @@ public:
|
|||||||
struct CBuildingData {
|
struct CBuildingData {
|
||||||
struct BuildingsData::building building;
|
struct BuildingsData::building building;
|
||||||
};
|
};
|
||||||
|
struct CBuildingSceneLoaded {};
|
||||||
|
struct CBuildingSceneLoad {};
|
||||||
|
struct CBuildingSceneUnload {};
|
||||||
struct CBTypeResidental {};
|
struct CBTypeResidental {};
|
||||||
struct CBCustomLayout {
|
struct CBCustomLayout {
|
||||||
int size;
|
int size;
|
||||||
@@ -65,39 +81,54 @@ public:
|
|||||||
struct CBuildingUnload {};
|
struct CBuildingUnload {};
|
||||||
struct CBuildingLoaded {};
|
struct CBuildingLoaded {};
|
||||||
struct CBuildingEdited {};
|
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:
|
public:
|
||||||
void get_scene_keys_list(List<String> *keys) const;
|
static void get_scene_keys_list(List<String> *keys);
|
||||||
bool has_scene(const String &key) const;
|
static bool has_scene(const String &key);
|
||||||
void remove_scene_item(const String &key, const String &bkey);
|
static AABB get_scene_aabb(const String &key);
|
||||||
void add_scene_item(const String &key, const String &bkey);
|
static void remove_scene_item(const String &key, const String &bkey);
|
||||||
void create_scene_data(const String &key, const String &bkey);
|
static void add_scene_item(const String &key, const String &bkey);
|
||||||
Ref<PackedScene> scene_get_packed_scene(const String &key) const;
|
static Ref<PackedScene> scene_get_packed_scene(const String &key);
|
||||||
int scene_get_item_count(const String &key) const;
|
static int scene_get_item_count(const String &key);
|
||||||
// String scene_get_item(const String &key, int index) const;
|
// String scene_get_item(const String &key, int index) const;
|
||||||
List<String> scene_get_items(const String &key) const;
|
static List<String> scene_get_items(const String &key);
|
||||||
void set_scene_item_node(const String &key, const String &bkey,
|
static void set_scene_item_node(const String &key, const String &bkey,
|
||||||
Node *node);
|
Node *node);
|
||||||
bool has_scene_item(const String &key, const String &bkey) const;
|
static bool has_scene_item(const String &key, const String &bkey);
|
||||||
Node *get_scene_item_node(const String &key, const String &bkey) const;
|
static Node *get_scene_item_node(const String &key, const String &bkey);
|
||||||
void save_buildings();
|
static void save_buildings();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node *item_nodes_get_node(const String &key) const;
|
static Node *item_nodes_get_node(const String &key);
|
||||||
|
|
||||||
private:
|
|
||||||
Error scene_loader_poll(const String &key);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void scene_update();
|
static void scene_update();
|
||||||
/* Path for each building type */
|
/* Path for each building type */
|
||||||
HashMap<String, String> building_data;
|
// HashMap<String, String> building_data;
|
||||||
HashMap<String, Vector<Transform> > building_doors;
|
// HashMap<String, Vector<Transform> > building_doors;
|
||||||
HashMap<String, AABB> building_aabbs;
|
// HashMap<String, AABB> building_aabbs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct building &get_building(const String &building_key);
|
static struct building &get_building(const String &building_key);
|
||||||
const struct building &get_building(const String &building_key) const;
|
|
||||||
struct callme {
|
struct callme {
|
||||||
class H {};
|
class H {};
|
||||||
H *obj;
|
H *obj;
|
||||||
@@ -126,8 +157,9 @@ public:
|
|||||||
void *)>(obj);
|
void *)>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void for_each_building(struct callme &c);
|
static void for_each_building(struct callme &c);
|
||||||
template <typename Func> void for_each_building(Func &&func, void *data)
|
template <typename Func>
|
||||||
|
static void for_each_building(Func &&func, void *data)
|
||||||
{
|
{
|
||||||
List<String> keys;
|
List<String> keys;
|
||||||
get_building_keys_list(&keys);
|
get_building_keys_list(&keys);
|
||||||
@@ -137,40 +169,41 @@ public:
|
|||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void for_each_building(void (*func)(const String &key, void *data),
|
static void for_each_building(void (*func)(const String &key,
|
||||||
|
void *data),
|
||||||
void *data);
|
void *data);
|
||||||
void get_building_keys_list(List<String> *keys);
|
static void get_building_keys_list(List<String> *keys);
|
||||||
|
|
||||||
int get_building_count() const;
|
static int get_building_count();
|
||||||
String create_building(const Dictionary &dict);
|
static String create_building(const Dictionary &dict);
|
||||||
String create_building(const struct building &building);
|
static String create_building(const struct building &building);
|
||||||
String create_building(const struct building *building);
|
static String create_building(const struct building *building);
|
||||||
bool destroy_building(const String &key);
|
static bool destroy_building(const String &key);
|
||||||
struct checkpoint_data {
|
struct checkpoint_data {
|
||||||
HashMap<String, String> building_data;
|
HashMap<String, String> building_data;
|
||||||
std::vector<struct building> buildings;
|
std::vector<struct building> buildings;
|
||||||
};
|
};
|
||||||
std::vector<struct checkpoint_data> undo_log;
|
std::vector<struct checkpoint_data> undo_log;
|
||||||
int undo_log_size;
|
int undo_log_size;
|
||||||
BuildingsData();
|
BuildingsData(flecs::world &e);
|
||||||
virtual ~BuildingsData();
|
virtual ~BuildingsData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read_buildings_json(const String &buildings_path);
|
static void read_buildings_json(const String &buildings_path);
|
||||||
void save_buildings_json(const String &buildings_path);
|
static void save_buildings_json(const String &buildings_path);
|
||||||
void filter_generated_stuff();
|
static void filter_generated_stuff();
|
||||||
void remove_generated_stuff();
|
static void remove_generated_stuff();
|
||||||
void load_data();
|
void load_data();
|
||||||
void checkpoint();
|
void checkpoint();
|
||||||
void undo();
|
void undo();
|
||||||
void fill_door_locations();
|
static void build_building_aabbs();
|
||||||
void build_building_aabbs();
|
static void update_building_transform(const String &key,
|
||||||
void update_building_transform(const String &key,
|
|
||||||
const Transform &xform);
|
const Transform &xform);
|
||||||
bool has_building(const String &key);
|
static bool has_building(const String &key);
|
||||||
String get_closest_building(const Transform &xform) const;
|
static String get_closest_building(const Transform &xform);
|
||||||
flecs::entity get_closest_building_entity(const Transform &xform) const;
|
static flecs::entity
|
||||||
flecs::entity get_building_entity(const String &key) const;
|
get_closest_building_entity(const Transform &xform);
|
||||||
|
static flecs::entity get_building_entity(const String &key);
|
||||||
void load_tile(int x, int z);
|
void load_tile(int x, int z);
|
||||||
};
|
};
|
||||||
#endif
|
#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 <scene/3d/immediate_geometry.h>
|
||||||
#include "wedge.h"
|
#include "wedge.h"
|
||||||
#include "base_data.h"
|
#include "base_data.h"
|
||||||
|
#include "buildings_data.h"
|
||||||
#include "contours.h"
|
#include "contours.h"
|
||||||
|
|
||||||
Contours *Contours::singleton = nullptr;
|
Contours::Contours(flecs::world &ecs)
|
||||||
|
|
||||||
Contours *Contours::get_singleton()
|
|
||||||
{
|
|
||||||
if (!singleton)
|
|
||||||
singleton = memnew(Contours);
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
Contours::Contours()
|
|
||||||
: dbg(nullptr)
|
: 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()
|
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;
|
int i, j;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -51,6 +51,7 @@ static Vector3 normal(const Vector3 &v)
|
|||||||
void Contours::build()
|
void Contours::build()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
print_line("Contours::build()");
|
||||||
contours.clear();
|
contours.clear();
|
||||||
for (i = 0; i < (int)wedge_contours.size(); i++) {
|
for (i = 0; i < (int)wedge_contours.size(); i++) {
|
||||||
struct main_contour mc;
|
struct main_contour mc;
|
||||||
@@ -86,10 +87,6 @@ void Contours::build()
|
|||||||
}
|
}
|
||||||
contours.push_back(mc);
|
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_queue;
|
||||||
List<struct Lot::polygon> polygon_output;
|
List<struct Lot::polygon> polygon_output;
|
||||||
Vector<struct Lot::polygon> check;
|
Vector<struct Lot::polygon> check;
|
||||||
@@ -141,7 +138,7 @@ void Contours::build()
|
|||||||
List<struct Lot::polygon>::Element *e = polygon_queue.front();
|
List<struct Lot::polygon>::Element *e = polygon_queue.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
struct Lot::polygon item = e->get();
|
struct Lot::polygon item = e->get();
|
||||||
print_line("queue: " + itos(polygon_queue.size()));
|
// print_line("queue: " + itos(polygon_queue.size()));
|
||||||
polygon_queue.pop_front();
|
polygon_queue.pop_front();
|
||||||
float area = item.area();
|
float area = item.area();
|
||||||
if (area > 120.0f * 120.0f &&
|
if (area > 120.0f * 120.0f &&
|
||||||
@@ -162,12 +159,15 @@ void Contours::build()
|
|||||||
e = polygon_queue.front();
|
e = polygon_queue.front();
|
||||||
}
|
}
|
||||||
e = polygon_output.front();
|
e = polygon_output.front();
|
||||||
|
assert(base_e.is_valid());
|
||||||
while (e) {
|
while (e) {
|
||||||
|
print_line("creating entity");
|
||||||
flecs::entity lot_e = BaseData::get_singleton()
|
flecs::entity lot_e = BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.entity()
|
.entity()
|
||||||
.child_of(base_e);
|
.child_of(base_e);
|
||||||
lot_e.set<Lot>({ e->get() });
|
lot_e.set<Lot>({ e->get() });
|
||||||
|
print_line("created entity: " + String(lot_e.name()));
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,7 +186,6 @@ void Contours::build()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Lot::pack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contours::debug()
|
void Contours::debug()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#ifndef CONTOURS_H_
|
#ifndef CONTOURS_H_
|
||||||
#define CONTOURS_H_
|
#define CONTOURS_H_
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <flecs.h>
|
||||||
#include "road_lot.h"
|
#include "road_lot.h"
|
||||||
|
|
||||||
class ImmediateGeometry;
|
class ImmediateGeometry;
|
||||||
@@ -20,12 +21,11 @@ struct Contours {
|
|||||||
Ref<SpatialMaterial> imm_mat;
|
Ref<SpatialMaterial> imm_mat;
|
||||||
std::vector<std::vector<struct wedge *> > wedge_contours;
|
std::vector<std::vector<struct wedge *> > wedge_contours;
|
||||||
std::vector<struct main_contour> contours;
|
std::vector<struct main_contour> contours;
|
||||||
static Contours *singleton;
|
Contours(flecs::world &ecs);
|
||||||
static Contours *get_singleton();
|
|
||||||
Contours();
|
|
||||||
virtual ~Contours();
|
virtual ~Contours();
|
||||||
bool is_in_closed_contour(const struct wedge *w);
|
bool is_in_closed_contour(const struct wedge *w) const;
|
||||||
void debug();
|
void debug();
|
||||||
|
flecs::entity base_e;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTOURS_H_
|
#endif // CONTOURS_H_
|
||||||
@@ -26,6 +26,7 @@ LineMetadataEditor::~LineMetadataEditor()
|
|||||||
|
|
||||||
void LineMetadataEditor::_notification(int which)
|
void LineMetadataEditor::_notification(int which)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
VBoxContainer *box = memnew(VBoxContainer);
|
VBoxContainer *box = memnew(VBoxContainer);
|
||||||
@@ -64,6 +65,7 @@ void LineMetadataEditor::_notification(int which)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineMetadataEditor::_bind_methods()
|
void LineMetadataEditor::_bind_methods()
|
||||||
|
|||||||
@@ -1125,7 +1125,7 @@ class EdgeEditorHandler {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const AABB &aabb_building =
|
const AABB &aabb_building =
|
||||||
bd()->building_aabbs[buildings[i].id];
|
bd()->get_scene_aabb(buildings[i].id);
|
||||||
Transform building_rot(
|
Transform building_rot(
|
||||||
Basis().rotated(
|
Basis().rotated(
|
||||||
Vector3(0, 1, 0),
|
Vector3(0, 1, 0),
|
||||||
@@ -1306,9 +1306,9 @@ class EdgeEditorHandler {
|
|||||||
String lot_id = side.lot_type;
|
String lot_id = side.lot_type;
|
||||||
if (side.buildings.size() > 1) {
|
if (side.buildings.size() > 1) {
|
||||||
const AABB &aabb_lot =
|
const AABB &aabb_lot =
|
||||||
bd()->building_aabbs
|
bd()->get_scene_aabb(
|
||||||
["lot-" +
|
"lot-" +
|
||||||
lot_id];
|
lot_id);
|
||||||
bool pack_result =
|
bool pack_result =
|
||||||
pack_buildings(
|
pack_buildings(
|
||||||
aabb_lot,
|
aabb_lot,
|
||||||
@@ -1375,9 +1375,9 @@ class EdgeEditorHandler {
|
|||||||
String lot_id = side.lot_type;
|
String lot_id = side.lot_type;
|
||||||
if (side.buildings.size() > 1) {
|
if (side.buildings.size() > 1) {
|
||||||
const AABB &aabb_lot =
|
const AABB &aabb_lot =
|
||||||
bd()->building_aabbs
|
bd()->get_scene_aabb(
|
||||||
["lot-" +
|
"lot-" +
|
||||||
lot_id];
|
lot_id);
|
||||||
bool pack_result =
|
bool pack_result =
|
||||||
pack_buildings(
|
pack_buildings(
|
||||||
aabb_lot,
|
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
|
bool Lot::polygon::intersects(const polygon *other) const
|
||||||
{
|
{
|
||||||
print_line("intersection_test");
|
// print_line("intersection_test");
|
||||||
dump();
|
// dump();
|
||||||
other->dump();
|
// other->dump();
|
||||||
Vector<Vector2> p1 = get_polygon2(points);
|
Vector<Vector2> p1 = get_polygon2(points);
|
||||||
Vector<Vector2> p2 = get_polygon2(other->points);
|
Vector<Vector2> p2 = get_polygon2(other->points);
|
||||||
Vector<Vector<Vector2> > intersection =
|
Vector<Vector<Vector2> > intersection =
|
||||||
@@ -510,14 +510,16 @@ struct LotPacker {
|
|||||||
lbs.clear();
|
lbs.clear();
|
||||||
Array lb = config.get_value("road", varname, Array());
|
Array lb = config.get_value("road", varname, Array());
|
||||||
int i, j;
|
int i, j;
|
||||||
|
print_line("start building list");
|
||||||
for (i = 0; i < (int)lb.size(); i++) {
|
for (i = 0; i < (int)lb.size(); i++) {
|
||||||
struct config_buildings cb;
|
struct config_buildings cb;
|
||||||
cb.area = 0.0f;
|
cb.area = 0.0f;
|
||||||
Array entries = lb[i];
|
Array entries = lb[i];
|
||||||
for (j = 0; j < entries.size(); j++) {
|
for (j = 0; j < entries.size(); j++) {
|
||||||
String bname = entries[j];
|
String bname = entries[j];
|
||||||
|
print_line("building: " + bname);
|
||||||
cb.buildings.push_back(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;
|
cb.area += aabb.size.x * aabb.size.z;
|
||||||
print_line("config building: " + bname);
|
print_line("config building: " + bname);
|
||||||
}
|
}
|
||||||
@@ -525,6 +527,7 @@ struct LotPacker {
|
|||||||
String::num(cb.area));
|
String::num(cb.area));
|
||||||
lbs.push_back(cb);
|
lbs.push_back(cb);
|
||||||
}
|
}
|
||||||
|
print_line("end building list");
|
||||||
struct lbsort {
|
struct lbsort {
|
||||||
_FORCE_INLINE_ bool
|
_FORCE_INLINE_ bool
|
||||||
operator()(const struct config_buildings &b1,
|
operator()(const struct config_buildings &b1,
|
||||||
@@ -536,29 +539,45 @@ struct LotPacker {
|
|||||||
lbs.sort_custom<struct lbsort>();
|
lbs.sort_custom<struct lbsort>();
|
||||||
lbs.invert();
|
lbs.invert();
|
||||||
}
|
}
|
||||||
LotPacker(Vector2 cell_size)
|
LotPacker(flecs::world &ecs)
|
||||||
: cell_size(cell_size)
|
: cell_size(Vector2(16, 16))
|
||||||
{
|
{
|
||||||
BaseData::get_singleton()->get().component<LotGrid>();
|
ecs.module<LotPacker>();
|
||||||
BaseData::get_singleton()->get().component<LotBuildings>();
|
ecs.import <BuildingsData>();
|
||||||
BaseData::get_singleton()->get().component<PreOccupied>();
|
ecs.component<LotGrid>();
|
||||||
BaseData::get_singleton()->get().component<Industrial>();
|
ecs.component<PreOccupied>();
|
||||||
BaseData::get_singleton()->get().component<Commercial>();
|
ecs.component<Industrial>();
|
||||||
BaseData::get_singleton()->get().component<Residental>();
|
ecs.component<Commercial>();
|
||||||
|
ecs.component<Residental>();
|
||||||
|
struct PackerState {
|
||||||
|
int state;
|
||||||
|
};
|
||||||
|
ecs.component<PackerState>();
|
||||||
|
|
||||||
Error err = config.load("res://config/stream.conf");
|
Error err = config.load("res://config/stream.conf");
|
||||||
assert(err == OK);
|
assert(err == OK);
|
||||||
get_building_list("lot_buildings_residental",
|
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);
|
lot_buildings_residental);
|
||||||
get_building_list("lot_buildings_commercial",
|
get_building_list(
|
||||||
|
"lot_buildings_commercial",
|
||||||
lot_buildings_commercial);
|
lot_buildings_commercial);
|
||||||
get_building_list("lot_buildings_industrial",
|
get_building_list(
|
||||||
|
"lot_buildings_industrial",
|
||||||
lot_buildings_industrial);
|
lot_buildings_industrial);
|
||||||
}
|
}
|
||||||
static LotPacker *get_singleton()
|
if (it.world().has<PackerState>())
|
||||||
{
|
it.world()
|
||||||
if (!singleton)
|
.get_mut<PackerState>()
|
||||||
singleton = memnew(LotPacker(Vector2(16, 16)));
|
->state++;
|
||||||
return singleton;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Rect2 aabb2rect(const AABB &aabb)
|
static inline Rect2 aabb2rect(const AABB &aabb)
|
||||||
@@ -840,17 +859,17 @@ out_bad:
|
|||||||
}
|
}
|
||||||
bool tmp_found = false;
|
bool tmp_found = false;
|
||||||
int office_count = 0;
|
int office_count = 0;
|
||||||
|
// FIXME use components and find instead of direct lookup
|
||||||
AABB get_building_aabb(const String &key) const
|
AABB get_building_aabb(const String &key) const
|
||||||
{
|
{
|
||||||
const struct BuildingsData::building &b =
|
const struct BuildingsData::building &b =
|
||||||
bd()->get_building(key);
|
bd()->get_building(key);
|
||||||
const AABB &building_aabb = bd()->building_aabbs[b.id];
|
return bd()->get_scene_aabb(b.id);
|
||||||
return building_aabb;
|
|
||||||
}
|
}
|
||||||
|
// FIXME use components and find instead of direct lookup
|
||||||
AABB get_building_type_aabb(const String &building) const
|
AABB get_building_type_aabb(const String &building) const
|
||||||
{
|
{
|
||||||
const AABB &building_aabb = bd()->building_aabbs[building];
|
return bd()->get_scene_aabb(building);
|
||||||
return building_aabb;
|
|
||||||
}
|
}
|
||||||
Transform get_building_transform(const String &key)
|
Transform get_building_transform(const String &key)
|
||||||
{
|
{
|
||||||
@@ -872,20 +891,34 @@ out_bad:
|
|||||||
void create()
|
void create()
|
||||||
{
|
{
|
||||||
int lot_count = 0;
|
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()
|
BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.query_builder<Lot>()
|
.query_builder<Lot>()
|
||||||
.write<LotBuildings>()
|
.read<PreOccupied>()
|
||||||
.write<PreOccupied>()
|
|
||||||
.build()
|
.build()
|
||||||
.each([&](flecs::entity e, Lot &lot_) {
|
.each([&](flecs::entity e, Lot &lot_) {
|
||||||
assert(e.get<Lot>()->polygon.points.size() > 0);
|
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();
|
e.get_mut<Lot>()->polygon.update_aabb();
|
||||||
if (e.has<PreOccupied>())
|
if (!e.has<PreOccupied>())
|
||||||
return;
|
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) {
|
while (be) {
|
||||||
const String &key = be->get();
|
const String &key = be->get();
|
||||||
const struct BuildingsData::building &b =
|
const struct BuildingsData::building &b =
|
||||||
@@ -898,54 +931,59 @@ out_bad:
|
|||||||
be = be->next();
|
be = be->next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AABB lot_aabb =
|
vbuildings.push_back(b);
|
||||||
e.get<Lot>()->polygon.aabb;
|
Rect2 building_rect = get_rect_transformed(b.key);
|
||||||
Rect2 lot_rect = aabb2rect(
|
vrects.push_back(building_rect);
|
||||||
e.get<Lot>()->polygon.aabb);
|
Transform xform = get_building_transform(b.key);
|
||||||
Rect2 building_rect =
|
xforms.push_back(xform);
|
||||||
get_rect_transformed(key);
|
be = be->next();
|
||||||
Transform xform =
|
}
|
||||||
get_building_transform(key);
|
print_line("buildings: " + itos(vbuildings.size()));
|
||||||
Vector2 building_pos = Vector2(
|
for (i = 0; i < entities.size(); i++) {
|
||||||
xform.origin.x, xform.origin.z);
|
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;
|
bool intersects = false;
|
||||||
if (e.get<Lot>()->polygon.is_inside(
|
if (e.get<Lot>()->polygon.is_inside(
|
||||||
building_rect))
|
building_rect))
|
||||||
intersects = true;
|
intersects = true;
|
||||||
assert(e.get<Lot>()
|
|
||||||
->polygon.points.size() >
|
|
||||||
0);
|
|
||||||
if (intersects) {
|
if (intersects) {
|
||||||
assert(e.get<Lot>()
|
|
||||||
->polygon.points
|
|
||||||
.size() > 0);
|
|
||||||
e.add<PreOccupied>();
|
e.add<PreOccupied>();
|
||||||
assert(e.get<Lot>()
|
|
||||||
->polygon.points
|
|
||||||
.size() > 0);
|
|
||||||
LotBuildings &lb =
|
LotBuildings &lb =
|
||||||
e.ensure<LotBuildings>();
|
e.ensure<LotBuildings>();
|
||||||
lb.buildings.push_back(
|
lb.buildings.push_back(
|
||||||
{ building_rect, key });
|
{ building_rect, b.key });
|
||||||
Vector<Vector2> pt =
|
Vector<Vector2> pt = get_polygon2(
|
||||||
get_polygon2(
|
e.get<Lot>()->polygon.points);
|
||||||
e.get<Lot>()
|
|
||||||
->polygon
|
|
||||||
.points);
|
|
||||||
assert(pt.size() > 0);
|
assert(pt.size() > 0);
|
||||||
lb.polygons.push_back(pt);
|
lb.polygons.push_back(pt);
|
||||||
e.modified<LotBuildings>();
|
e.modified<LotBuildings>();
|
||||||
}
|
}
|
||||||
be = be->next();
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
BaseData::get_singleton()
|
BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.query_builder<Lot, LotBuildings>()
|
.query_builder<Lot, LotBuildings>()
|
||||||
.with<PreOccupied>()
|
.with<PreOccupied>()
|
||||||
.build()
|
.build()
|
||||||
.each([&](flecs::entity e, Lot &lot, LotBuildings &lb) {
|
.each([&](flecs::entity e, Lot &lot, LotBuildings &lb) {
|
||||||
int i;
|
|
||||||
for (i = 0; i < lb.buildings.size(); i++) {
|
for (i = 0; i < lb.buildings.size(); i++) {
|
||||||
const Pair<Rect2, String> &mp =
|
const Pair<Rect2, String> &mp =
|
||||||
lb.buildings[i];
|
lb.buildings[i];
|
||||||
@@ -956,6 +994,9 @@ out_bad:
|
|||||||
get_rect_transformed(key);
|
get_rect_transformed(key);
|
||||||
Rect2 lot_rect =
|
Rect2 lot_rect =
|
||||||
aabb2rect(lot.polygon.aabb);
|
aabb2rect(lot.polygon.aabb);
|
||||||
|
assert(bd()->has_scene(
|
||||||
|
"office-exterior"));
|
||||||
|
print_line("building type: " + b.id);
|
||||||
if (b.id == "office-exterior") {
|
if (b.id == "office-exterior") {
|
||||||
print_line("id: " + b.id);
|
print_line("id: " + b.id);
|
||||||
print_line("xform: " +
|
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()
|
BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.query_builder<Lot>()
|
.query_builder<Lot>()
|
||||||
@@ -1080,14 +1134,12 @@ out_bad:
|
|||||||
e.add<Residental>();
|
e.add<Residental>();
|
||||||
lot_count++;
|
lot_count++;
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
assert(tmp_found);
|
assert(tmp_found);
|
||||||
print_line("office_count: " + itos(office_count));
|
print_line("office_count: " + itos(office_count));
|
||||||
// assert(office_count > 1);
|
// assert(office_count > 1);
|
||||||
BaseData::get_singleton()
|
for (i = 0; i < entities_all.size(); i++)
|
||||||
->get()
|
add_lot(entities_all[i]);
|
||||||
.query_builder<Lot>()
|
|
||||||
.build()
|
|
||||||
.each([&](flecs::entity e, Lot &lot) { add_lot(e); });
|
|
||||||
BaseData::get_singleton()
|
BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.query_builder<Lot>()
|
.query_builder<Lot>()
|
||||||
@@ -1292,31 +1344,42 @@ out_bad:
|
|||||||
return lb->polygons;
|
return lb->polygons;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
LotPacker *LotPacker::singleton = nullptr;
|
|
||||||
|
|
||||||
void Lot::pack()
|
void Lot::pack()
|
||||||
{
|
{
|
||||||
LotPacker::get_singleton()->create();
|
BaseData::get_singleton()->get().get_mut<LotPacker>()->create();
|
||||||
LotPacker::get_singleton()->pack_lots();
|
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)
|
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)
|
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,
|
void Lot::get_lot_buildings(flecs::entity e,
|
||||||
Vector<Pair<Rect2, String> > *lot_buildings)
|
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)
|
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,
|
get_lot_buildings(flecs::entity e,
|
||||||
Vector<Pair<Rect2, String> > *lot_buildings);
|
Vector<Pair<Rect2, String> > *lot_buildings);
|
||||||
static Vector<Vector<Vector2> > get_lot_polygons(flecs::entity e);
|
static Vector<Vector<Vector2> > get_lot_polygons(flecs::entity e);
|
||||||
|
static void import_packer(flecs::world &ecs);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ROAD_LOT_H_
|
#endif // ROAD_LOT_H_
|
||||||
@@ -88,9 +88,10 @@ struct RoadLinesProcessing {
|
|||||||
int debug_flags;
|
int debug_flags;
|
||||||
DebugGeo *dbg;
|
DebugGeo *dbg;
|
||||||
static ConfigFile config;
|
static ConfigFile config;
|
||||||
RoadLinesProcessing()
|
RoadLinesProcessing(flecs::world &ecs)
|
||||||
: dbg(nullptr)
|
: dbg(nullptr)
|
||||||
{
|
{
|
||||||
|
ecs.module<RoadLinesProcessing>();
|
||||||
Error err = config.load("res://config/stream.conf");
|
Error err = config.load("res://config/stream.conf");
|
||||||
assert(err == OK);
|
assert(err == OK);
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,7 @@ struct RoadLinesProcessing {
|
|||||||
}
|
}
|
||||||
bd()->create_building(b);
|
bd()->create_building(b);
|
||||||
if (!bd()->has_scene(b.id))
|
if (!bd()->has_scene(b.id))
|
||||||
bd()->create_scene_data(b.id, b.key);
|
return;
|
||||||
else
|
else
|
||||||
bd()->add_scene_item(b.id, b.key);
|
bd()->add_scene_item(b.id, b.key);
|
||||||
print_line("created building: " + b.key + " " + b.id);
|
print_line("created building: " + b.key + " " + b.id);
|
||||||
@@ -919,7 +920,10 @@ out2:;
|
|||||||
void find_closed_contours()
|
void find_closed_contours()
|
||||||
{
|
{
|
||||||
int i, j;
|
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 = BaseData::get_singleton() ->get() .get_mut<RoadLinesProcessing>();
|
||||||
RoadLinesProcessing *r = this;
|
RoadLinesProcessing *r = this;
|
||||||
if (r->nodes.size() == 0)
|
if (r->nodes.size() == 0)
|
||||||
@@ -985,7 +989,7 @@ out2:;
|
|||||||
}
|
}
|
||||||
if (finished) {
|
if (finished) {
|
||||||
int k;
|
int k;
|
||||||
print_line("complete contour");
|
// print_line("complete contour");
|
||||||
std::vector<struct wedge *> wedge_contour;
|
std::vector<struct wedge *> wedge_contour;
|
||||||
Vector<Vector2> polygon;
|
Vector<Vector2> polygon;
|
||||||
for (k = 0; k < (int)contour.size(); k++) {
|
for (k = 0; k < (int)contour.size(); k++) {
|
||||||
@@ -993,8 +997,8 @@ out2:;
|
|||||||
wedges_ref[contour[k]];
|
wedges_ref[contour[k]];
|
||||||
wedge_contour.push_back(
|
wedge_contour.push_back(
|
||||||
&wedges[wr.first][wr.second]);
|
&wedges[wr.first][wr.second]);
|
||||||
print_line(itos(k) + ": " +
|
// print_line(itos(k) + ": " +
|
||||||
itos(contour[k]));
|
// itos(contour[k]));
|
||||||
Vector3 p1 =
|
Vector3 p1 =
|
||||||
wedges[wr.first][wr.second].p[0];
|
wedges[wr.first][wr.second].p[0];
|
||||||
Vector3 p2 =
|
Vector3 p2 =
|
||||||
@@ -1007,8 +1011,7 @@ out2:;
|
|||||||
used.push_back(contour[k]);
|
used.push_back(contour[k]);
|
||||||
}
|
}
|
||||||
if (Geometry::is_polygon_clockwise(polygon))
|
if (Geometry::is_polygon_clockwise(polygon))
|
||||||
contours->get_singleton()
|
contours->wedge_contours.push_back(
|
||||||
->wedge_contours.push_back(
|
|
||||||
wedge_contour);
|
wedge_contour);
|
||||||
contour.clear();
|
contour.clear();
|
||||||
contour_count++;
|
contour_count++;
|
||||||
@@ -1018,8 +1021,6 @@ out2:;
|
|||||||
if (base >= (int)wedges_ref.size())
|
if (base >= (int)wedges_ref.size())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
contours->build();
|
|
||||||
contours->debug();
|
|
||||||
}
|
}
|
||||||
~RoadLinesProcessing()
|
~RoadLinesProcessing()
|
||||||
{
|
{
|
||||||
@@ -1032,27 +1033,10 @@ out2:;
|
|||||||
{
|
{
|
||||||
return debug_flags;
|
return debug_flags;
|
||||||
}
|
}
|
||||||
void road_setup()
|
void road_setup2()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
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();
|
// update_lot_depths();
|
||||||
ImmediateGeometry *d = rld->get_debug_node();
|
ImmediateGeometry *d = rld->get_debug_node();
|
||||||
d->clear();
|
d->clear();
|
||||||
@@ -1114,7 +1098,6 @@ out2:;
|
|||||||
}
|
}
|
||||||
d->end();
|
d->end();
|
||||||
}
|
}
|
||||||
create_structures();
|
|
||||||
print_line("ROAD SETUP DONE");
|
print_line("ROAD SETUP DONE");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1703,7 +1686,9 @@ public:
|
|||||||
out_surfaces[h], 0.0f);
|
out_surfaces[h], 0.0f);
|
||||||
} else if (k == params.nlanes + 1 &&
|
} else if (k == params.nlanes + 1 &&
|
||||||
mside1.lot > 0) { /* lot */
|
mside1.lot > 0) { /* lot */
|
||||||
if (!Contours::get_singleton()
|
if (!BaseData::get_singleton()
|
||||||
|
->get()
|
||||||
|
.get<Contours>()
|
||||||
->is_in_closed_contour(
|
->is_in_closed_contour(
|
||||||
&wedge))
|
&wedge))
|
||||||
build_split_segment(
|
build_split_segment(
|
||||||
@@ -1779,7 +1764,9 @@ public:
|
|||||||
"m2: " +
|
"m2: " +
|
||||||
String::num(
|
String::num(
|
||||||
mside2.lot_depth_eff));
|
mside2.lot_depth_eff));
|
||||||
if (!Contours::get_singleton()
|
if (!BaseData::get_singleton()
|
||||||
|
->get()
|
||||||
|
.get<Contours>()
|
||||||
->is_in_closed_contour(
|
->is_in_closed_contour(
|
||||||
&wedge))
|
&wedge))
|
||||||
build_split_segment(
|
build_split_segment(
|
||||||
@@ -1864,25 +1851,51 @@ public:
|
|||||||
nodes_mi.push_back(mi);
|
nodes_mi.push_back(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RoadMeshProcessing()
|
RoadMeshProcessing(flecs::world &ecs)
|
||||||
: road_mgroup(nullptr)
|
: road_mgroup(nullptr)
|
||||||
{
|
{
|
||||||
BaseData::get_singleton()->get().ensure<RoadLinesProcessing>();
|
ecs.module<RoadMeshProcessing>();
|
||||||
|
ecs.import <RoadLinesProcessing>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void RoadProcessing::road_setup(Node *target, int debug_flags)
|
void RoadProcessing::road_setup(Node *target, int debug_flags)
|
||||||
{
|
{
|
||||||
BaseData::get_singleton()->get().ensure<RoadLinesProcessing>();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
BaseData::get_singleton()->get().ensure<RoadMeshProcessing>();
|
int i, j;
|
||||||
RoadLinesProcessing *r =
|
RoadLinesProcessing *r =
|
||||||
BaseData::get_singleton()->get().get_mut<RoadLinesProcessing>();
|
BaseData::get_singleton()->get().get_mut<RoadLinesProcessing>();
|
||||||
r->set_debug_flags(debug_flags);
|
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()
|
BaseData::get_singleton()
|
||||||
->get()
|
->get()
|
||||||
.get_mut<RoadMeshProcessing>()
|
.get_mut<RoadMeshProcessing>()
|
||||||
->create_road_meshes(target);
|
->create_road_meshes(target);
|
||||||
|
r->road_setup2();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoadProcessing::remove_road_meshes(Node *target)
|
void RoadProcessing::remove_road_meshes(Node *target)
|
||||||
@@ -1900,7 +1913,6 @@ void RoadProcessing::load_data()
|
|||||||
ConfigFile config;
|
ConfigFile config;
|
||||||
Error result = config.load("res://config/stream.conf");
|
Error result = config.load("res://config/stream.conf");
|
||||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
BaseData::get_singleton()->get().ensure<RoadMeshProcessing>();
|
|
||||||
RoadMeshProcessing *rmp =
|
RoadMeshProcessing *rmp =
|
||||||
BaseData::get_singleton()->get().get_mut<RoadMeshProcessing>();
|
BaseData::get_singleton()->get().get_mut<RoadMeshProcessing>();
|
||||||
assert(rmp);
|
assert(rmp);
|
||||||
@@ -2025,3 +2037,15 @@ void RoadProcessing::cleanup()
|
|||||||
BaseData::get_singleton()->get().remove<RoadLinesProcessing>();
|
BaseData::get_singleton()->get().remove<RoadLinesProcessing>();
|
||||||
BaseData::get_singleton()->get().remove<RoadMeshProcessing>();
|
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_
|
#ifndef ROAD_LINES_PROCESSING_H_
|
||||||
#define ROAD_LINES_PROCESSSING_H_
|
#define ROAD_LINES_PROCESSSING_H_
|
||||||
|
#include <flecs.h>
|
||||||
class Node;
|
class Node;
|
||||||
class ImmediateGeometry;
|
class ImmediateGeometry;
|
||||||
class RoadProcessing {
|
class RoadProcessing {
|
||||||
@@ -8,5 +9,7 @@ public:
|
|||||||
static void remove_road_meshes(Node *target);
|
static void remove_road_meshes(Node *target);
|
||||||
static void load_data();
|
static void load_data();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
RoadProcessing(flecs::world &ecs);
|
||||||
|
virtual ~RoadProcessing();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void StreamWorld::create_tilemap()
|
|||||||
|
|
||||||
void StreamWorld::update_view()
|
void StreamWorld::update_view()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
ERR_FAIL_COND_MSG(!initialized,
|
ERR_FAIL_COND_MSG(!initialized,
|
||||||
"The Stream object is incorrectly initialized");
|
"The Stream object is incorrectly initialized");
|
||||||
if (!viewer || !terrain) {
|
if (!viewer || !terrain) {
|
||||||
@@ -84,6 +84,12 @@ void StreamWorld::update_view()
|
|||||||
ERR_FAIL_COND_MSG(!t, "VoxelLodTerrain was not found");
|
ERR_FAIL_COND_MSG(!t, "VoxelLodTerrain was not found");
|
||||||
viewer = v;
|
viewer = v;
|
||||||
terrain = t;
|
terrain = t;
|
||||||
|
assert(terrain);
|
||||||
|
assert(viewer);
|
||||||
|
BaseData::get_singleton()
|
||||||
|
->get()
|
||||||
|
.set<StreamWorld::components::WorldData>(
|
||||||
|
{ viewer, terrain });
|
||||||
viewer->connect("tree_exiting", this, "viewer_dead");
|
viewer->connect("tree_exiting", this, "viewer_dead");
|
||||||
terrain->connect("tree_exiting", this, "terrain_dead");
|
terrain->connect("tree_exiting", this, "terrain_dead");
|
||||||
current_x = world_extent + 1;
|
current_x = world_extent + 1;
|
||||||
@@ -218,7 +224,7 @@ void StreamWorld::unload_building(const String &key)
|
|||||||
void StreamWorld::update_items()
|
void StreamWorld::update_items()
|
||||||
{
|
{
|
||||||
List<String> keys;
|
List<String> keys;
|
||||||
data()->get_scene_keys_list(&keys);
|
BuildingsData::get_scene_keys_list(&keys);
|
||||||
List<String>::Element *e = keys.front();
|
List<String>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
const String &key = e->get();
|
const String &key = e->get();
|
||||||
@@ -260,6 +266,7 @@ void StreamWorld::remove_building(const String &key)
|
|||||||
|
|
||||||
VoxelLodTerrain *StreamWorld::get_terrain()
|
VoxelLodTerrain *StreamWorld::get_terrain()
|
||||||
{
|
{
|
||||||
|
assert(terrain);
|
||||||
return terrain;
|
return terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +323,7 @@ void StreamWorld::run_command(const String &command,
|
|||||||
String new_type = args[1];
|
String new_type = args[1];
|
||||||
Dictionary buildings_data =
|
Dictionary buildings_data =
|
||||||
config.get_value("buildings", "building_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);
|
print_error("unknown building type: " + new_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -403,7 +410,7 @@ void StreamWorld::run_command(const String &command,
|
|||||||
create_tilemap();
|
create_tilemap();
|
||||||
#endif
|
#endif
|
||||||
update_view();
|
update_view();
|
||||||
data()->scene_update();
|
BuildingsData::scene_update();
|
||||||
update_items();
|
update_items();
|
||||||
#if 0
|
#if 0
|
||||||
data()->for_each_building(
|
data()->for_each_building(
|
||||||
@@ -453,7 +460,17 @@ void StreamWorld::_notification(int which)
|
|||||||
if (current_scene)
|
if (current_scene)
|
||||||
current_scene = get_tree()->get_root();
|
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");
|
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);
|
RoadProcessing::road_setup(this, 0);
|
||||||
#if 0
|
#if 0
|
||||||
data()->for_each_building(
|
data()->for_each_building(
|
||||||
@@ -471,6 +488,7 @@ void StreamWorld::_notification(int which)
|
|||||||
#if 0
|
#if 0
|
||||||
create_tilemap();
|
create_tilemap();
|
||||||
#endif
|
#endif
|
||||||
|
BaseData::get_singleton()->get().defer_resume();
|
||||||
set_process(true);
|
set_process(true);
|
||||||
if (Engine::get_singleton()->is_editor_hint())
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
break;
|
break;
|
||||||
@@ -480,12 +498,14 @@ void StreamWorld::_notification(int which)
|
|||||||
update_view();
|
update_view();
|
||||||
assert(terrain);
|
assert(terrain);
|
||||||
assert(viewer);
|
assert(viewer);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_PROCESS: {
|
case NOTIFICATION_PROCESS: {
|
||||||
|
#if 0
|
||||||
if (frame_count % 60 == 0) {
|
if (frame_count % 60 == 0) {
|
||||||
float fmon = Performance::get_singleton()->get_monitor(
|
float fmon = Performance::get_singleton()->get_monitor(
|
||||||
Performance::RENDER_DRAW_CALLS_IN_FRAME);
|
Performance::RENDER_DRAW_CALLS_IN_FRAME);
|
||||||
@@ -497,6 +517,12 @@ void StreamWorld::_notification(int which)
|
|||||||
update_view();
|
update_view();
|
||||||
data()->scene_update();
|
data()->scene_update();
|
||||||
update_items();
|
update_items();
|
||||||
|
#endif
|
||||||
|
if (road_setup_needed && !road_setup_complete) {
|
||||||
|
road_setup();
|
||||||
|
road_setup_needed = false;
|
||||||
|
road_setup_complete = true;
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -525,14 +551,30 @@ StreamWorld::StreamWorld()
|
|||||||
, view_distance(0)
|
, view_distance(0)
|
||||||
, initialized(false)
|
, initialized(false)
|
||||||
, frame_count(0)
|
, 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");
|
Error result = config.load("res://config/stream.conf");
|
||||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
BaseData::get_singleton()->get().ensure<BuildingsData>();
|
|
||||||
RoadProcessing::load_data();
|
RoadProcessing::load_data();
|
||||||
world_extent = config.get_value("world", "world_extent");
|
world_extent = config.get_value("world", "world_extent");
|
||||||
tile_size = config.get_value("world", "tile_size");
|
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 ||
|
ERR_FAIL_COND_MSG(tile_size <= 0 || world_extent <= 0 ||
|
||||||
world_extent <= tile_size,
|
world_extent <= tile_size,
|
||||||
"Failed to configure world");
|
"Failed to configure world");
|
||||||
@@ -548,11 +590,40 @@ StreamWorld::StreamWorld()
|
|||||||
map_it++;
|
map_it++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
view_distance = config.get_value("world", "view_distance");
|
|
||||||
BaseData::get_singleton()->get().import <NPC>();
|
BaseData::get_singleton()->get().import <NPC>();
|
||||||
flecs::entity npcctrl = BaseData::get_singleton()->get().entity();
|
flecs::entity npcctrl = BaseData::get_singleton()->get().entity();
|
||||||
npcctrl.set<NPC::NPCControl>({ NPC::NPCControl::CMD_PRESIM });
|
npcctrl.set<NPC::NPCControl>({ NPC::NPCControl::CMD_PRESIM });
|
||||||
initialized = true;
|
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()
|
void StreamWorld::cleanup()
|
||||||
{
|
{
|
||||||
@@ -592,3 +663,16 @@ void StreamWorld::undo()
|
|||||||
update_view();
|
update_view();
|
||||||
update_items();
|
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;
|
bool initialized;
|
||||||
int current_x, current_z;
|
int current_x, current_z;
|
||||||
int frame_count;
|
int frame_count;
|
||||||
|
bool road_setup_needed;
|
||||||
|
bool road_setup_complete;
|
||||||
|
int count_shit;
|
||||||
void _notification(int which);
|
void _notification(int which);
|
||||||
// void create_tilemap();
|
// void create_tilemap();
|
||||||
void update_view();
|
void update_view();
|
||||||
@@ -51,10 +54,20 @@ private:
|
|||||||
void remove_generated_stuff();
|
void remove_generated_stuff();
|
||||||
void place_zebras();
|
void place_zebras();
|
||||||
void undo();
|
void undo();
|
||||||
|
void road_setup();
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct components {
|
||||||
|
struct Initialized {};
|
||||||
|
struct WorldData {
|
||||||
|
VoxelViewer *viewer;
|
||||||
|
VoxelLodTerrain *terrain;
|
||||||
|
};
|
||||||
|
struct RoadSetupNeeded {};
|
||||||
|
struct RoadSetupDone {};
|
||||||
|
};
|
||||||
VoxelLodTerrain *get_terrain();
|
VoxelLodTerrain *get_terrain();
|
||||||
void run_command(const String &command, const Vector<Variant> &args);
|
void run_command(const String &command, const Vector<Variant> &args);
|
||||||
StreamWorld();
|
StreamWorld();
|
||||||
|
|||||||
@@ -34,8 +34,14 @@ void TerrainEditor::exit()
|
|||||||
|
|
||||||
void TerrainEditor::update(float delta)
|
void TerrainEditor::update(float delta)
|
||||||
{
|
{
|
||||||
if (!active)
|
if (!active) {
|
||||||
|
if (BaseData::get_singleton()
|
||||||
|
->get()
|
||||||
|
.has<StreamWorld::components::WorldData>())
|
||||||
activate();
|
activate();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!cursor_enabled && get_camera_mode() == 3) {
|
if (!cursor_enabled && get_camera_mode() == 3) {
|
||||||
cursor_enabled = true;
|
cursor_enabled = true;
|
||||||
get_as_node<Spatial>(cursor_name)->show();
|
get_as_node<Spatial>(cursor_name)->show();
|
||||||
@@ -382,7 +388,7 @@ end:;
|
|||||||
"building elevation: " +
|
"building elevation: " +
|
||||||
String::num(imgmapper->get_height_full(
|
String::num(imgmapper->get_height_full(
|
||||||
b.xform.origin)));
|
b.xform.origin)));
|
||||||
AABB aabb = bd()->building_aabbs[b.id];
|
AABB aabb = bd()->get_scene_aabb(b.id);
|
||||||
print_line("building AABB: " +
|
print_line("building AABB: " +
|
||||||
(aabb.operator String()));
|
(aabb.operator String()));
|
||||||
float max_elevation_c = -Math_INF,
|
float max_elevation_c = -Math_INF,
|
||||||
|
|||||||
@@ -614,6 +614,7 @@ void MainTabs::_notification(int which)
|
|||||||
std::vector<Variant> args_data = {
|
std::vector<Variant> args_data = {
|
||||||
items[i].header
|
items[i].header
|
||||||
};
|
};
|
||||||
|
assert(items[i].header.length() > 0);
|
||||||
ui_field::ui_field_builder(this, tab,
|
ui_field::ui_field_builder(this, tab,
|
||||||
"l_p{v{}}",
|
"l_p{v{}}",
|
||||||
args_data.data(),
|
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>()
|
.get<WorldEditor::components::buildings_editor_node>()
|
||||||
->node;
|
->node;
|
||||||
assert(owner->is_inside_tree());
|
assert(owner->is_inside_tree());
|
||||||
for (i = 0; i < format.length(); i++) {
|
CharString cformat = format.ascii();
|
||||||
const char *fmt = format.ascii().ptr();
|
for (i = 0; i < format.ascii().length(); i++) {
|
||||||
int c = fmt[i];
|
assert(i < cformat.length());
|
||||||
|
int c = (int)cformat.ptr()[i];
|
||||||
// printf("character: %c : argp: %d\n", (char)c, argp);
|
// printf("character: %c : argp: %d\n", (char)c, argp);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '{':
|
case '{':
|
||||||
|
|||||||
Reference in New Issue
Block a user