Made accessor for lines
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -67,7 +67,8 @@
|
|||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"variant": "cpp",
|
"variant": "cpp",
|
||||||
"format": "cpp"
|
"format": "cpp",
|
||||||
|
"future": "cpp"
|
||||||
},
|
},
|
||||||
"cmake.ignoreCMakeListsMissing": true
|
"cmake.ignoreCMakeListsMissing": true
|
||||||
}
|
}
|
||||||
32
src/modules/stream/base_data.cpp
Normal file
32
src/modules/stream/base_data.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <core/os/memory.h>
|
||||||
|
#include "base_data.h"
|
||||||
|
|
||||||
|
static BaseData *base_data = nullptr;
|
||||||
|
|
||||||
|
BaseData::BaseData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
flecs::world &BaseData::get()
|
||||||
|
{
|
||||||
|
return ecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseData::~BaseData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseData *BaseData::get_singleton()
|
||||||
|
{
|
||||||
|
if (!base_data)
|
||||||
|
base_data = memnew(BaseData);
|
||||||
|
return base_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseData::cleanup()
|
||||||
|
{
|
||||||
|
if (base_data) {
|
||||||
|
memdelete(base_data);
|
||||||
|
base_data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/modules/stream/base_data.h
Normal file
13
src/modules/stream/base_data.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include "flecs/flecs.h"
|
||||||
|
class BaseData {
|
||||||
|
flecs::world ecs;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseData();
|
||||||
|
|
||||||
|
public:
|
||||||
|
flecs::world &get();
|
||||||
|
virtual ~BaseData();
|
||||||
|
static BaseData *get_singleton();
|
||||||
|
void cleanup();
|
||||||
|
};
|
||||||
@@ -10,24 +10,42 @@
|
|||||||
#include <scene/3d/spatial.h>
|
#include <scene/3d/spatial.h>
|
||||||
#include <scene/3d/mesh_instance.h>
|
#include <scene/3d/mesh_instance.h>
|
||||||
#include "from_string.h"
|
#include "from_string.h"
|
||||||
#include "flecs/flecs.h"
|
#include "base_data.h"
|
||||||
#include "buildings_data.h"
|
#include "buildings_data.h"
|
||||||
|
|
||||||
BuildingsData *BuildingsData::singleton;
|
BuildingsData *BuildingsData::singleton;
|
||||||
|
|
||||||
static ConfigFile config;
|
static ConfigFile config;
|
||||||
static flecs::world ecs;
|
|
||||||
struct scene_data {
|
struct scene_data {
|
||||||
Ref<PackedScene> packed_scene;
|
Ref<PackedScene> packed_scene;
|
||||||
String path;
|
String path;
|
||||||
Ref<ResourceInteractiveLoader> loader;
|
Ref<ResourceInteractiveLoader> loader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static flecs::world &ecs()
|
||||||
|
{
|
||||||
|
return BaseData::get_singleton()->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
static flecs::entity lookup(const String &key)
|
||||||
|
{
|
||||||
|
return ecs().lookup(key.ascii().ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
static flecs::entity lookup(const char *key)
|
||||||
|
{
|
||||||
|
return ecs().lookup(key);
|
||||||
|
}
|
||||||
|
|
||||||
struct CBuildingInstance {
|
struct CBuildingInstance {
|
||||||
String key;
|
String key;
|
||||||
Node *node;
|
Node *node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CBuildingData {
|
||||||
|
struct BuildingsData::building building;
|
||||||
|
};
|
||||||
|
|
||||||
struct CSceneData {
|
struct CSceneData {
|
||||||
struct scene_data sd;
|
struct scene_data sd;
|
||||||
};
|
};
|
||||||
@@ -38,6 +56,15 @@ BuildingsData::BuildingsData()
|
|||||||
load_data();
|
load_data();
|
||||||
fill_door_locations();
|
fill_door_locations();
|
||||||
build_building_aabbs();
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildingsData::~BuildingsData()
|
BuildingsData::~BuildingsData()
|
||||||
@@ -99,28 +126,27 @@ void BuildingsData::update_building_transform(const String &key,
|
|||||||
|
|
||||||
bool BuildingsData::has_building(const String &key)
|
bool BuildingsData::has_building(const String &key)
|
||||||
{
|
{
|
||||||
int index = get_building_by_key(key);
|
String ename = "base:" + key;
|
||||||
if (index >= 0)
|
flecs::entity e = lookup(ename.ascii().ptr());
|
||||||
return true;
|
return e.is_valid();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String BuildingsData::get_closest_building(const Transform &xform)
|
String BuildingsData::get_closest_building(const Transform &xform)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
float dst = Math_INF;
|
float dst = Math_INF;
|
||||||
String rkey;
|
String rkey;
|
||||||
int id = -1;
|
// int id = -1;
|
||||||
for (i = 0; i < (int)buildings_.size(); i++) {
|
ecs().each(
|
||||||
Vector3 o = xform.origin;
|
[xform, &rkey, &dst](flecs::entity e, const CBuildingData &d) {
|
||||||
Vector3 m = buildings_[i].xform.origin;
|
Vector3 o = xform.origin;
|
||||||
float mdst = o.distance_squared_to(m);
|
Vector3 m = d.building.xform.origin;
|
||||||
if (dst > mdst) {
|
float mdst = o.distance_squared_to(m);
|
||||||
dst = mdst;
|
if (dst > mdst) {
|
||||||
id = i;
|
dst = mdst;
|
||||||
}
|
rkey = d.building.key;
|
||||||
}
|
}
|
||||||
return buildings_[id].key;
|
});
|
||||||
|
return rkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::cleanup()
|
void BuildingsData::cleanup()
|
||||||
@@ -132,19 +158,6 @@ void BuildingsData::cleanup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BuildingsData::get_building_by_key(const String &key) const
|
|
||||||
{
|
|
||||||
int i, index = -1;
|
|
||||||
uint64_t key_hash = key.hash64();
|
|
||||||
for (i = 0; i < (int)buildings_.size(); i++) {
|
|
||||||
if (key_hash == buildings_[i].key_hash) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingsData::read_buildings_json(const String &buildings_path)
|
void BuildingsData::read_buildings_json(const String &buildings_path)
|
||||||
{
|
{
|
||||||
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
||||||
@@ -172,30 +185,17 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
|
|||||||
entry["xform"] = key;
|
entry["xform"] = key;
|
||||||
if (!entry.has("key")) // legacy
|
if (!entry.has("key")) // legacy
|
||||||
entry["key"] = key;
|
entry["key"] = key;
|
||||||
building::from_dict(&b, json[key]);
|
create_building(entry);
|
||||||
buildings_.push_back(b);
|
// building::from_dict(&b, json[key]);
|
||||||
|
// buildings_.push_back(b);
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
/* Transform */
|
|
||||||
print_line("key: " + key);
|
|
||||||
String id = json[key].get("id");
|
|
||||||
print_line("id: " + id);
|
|
||||||
String aabb = json[key].get("aabb");
|
|
||||||
print_line("aabb: " + aabb);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
filter_generated_stuff();
|
filter_generated_stuff();
|
||||||
print_line("entries count: " + itos(buildings_.size()));
|
print_line("entries count: " + itos(get_building_count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::save_buildings_json(const String &buildings_path)
|
void BuildingsData::save_buildings_json(const String &buildings_path)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
||||||
String backup_path = buildings_path + ".bak";
|
String backup_path = buildings_path + ".bak";
|
||||||
String store_path = buildings_path;
|
String store_path = buildings_path;
|
||||||
@@ -204,17 +204,19 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
|
|||||||
fa->store_string(buildings_json);
|
fa->store_string(buildings_json);
|
||||||
fa->close();
|
fa->close();
|
||||||
Dictionary json;
|
Dictionary json;
|
||||||
for (i = 0; i < (int)buildings_.size(); i++) {
|
int index = 0;
|
||||||
String key = buildings_[i].key;
|
ecs().each([&index, &json](const CBuildingData &b) {
|
||||||
Dictionary dict = buildings_[i].to_dict();
|
String key = b.building.key;
|
||||||
dict["index"] = i;
|
Dictionary dict = b.building.to_dict();
|
||||||
|
dict["index"] = index;
|
||||||
json[key] = dict;
|
json[key] = dict;
|
||||||
}
|
index++;
|
||||||
|
});
|
||||||
String json_string = JSON::print(json, "\t", false);
|
String json_string = JSON::print(json, "\t", false);
|
||||||
fa = FileAccess::open(store_path, FileAccess::WRITE);
|
fa = FileAccess::open(store_path, FileAccess::WRITE);
|
||||||
fa->store_string(json_string);
|
fa->store_string(json_string);
|
||||||
fa->close();
|
fa->close();
|
||||||
print_line("entries count: " + itos(buildings_.size()));
|
print_line("entries count: " + itos(get_building_count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::building::from_dict(building *b, const Dictionary &dict)
|
void BuildingsData::building::from_dict(building *b, const Dictionary &dict)
|
||||||
@@ -294,16 +296,16 @@ void BuildingsData::filter_generated_stuff()
|
|||||||
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");
|
||||||
Array gen_prefixes = config.get_value("lines", "gen_prefixes");
|
Array gen_prefixes = config.get_value("lines", "gen_prefixes");
|
||||||
int i, j;
|
ecs().each([gen_prefixes](CBuildingData &b) {
|
||||||
for (i = 0; i < (int)buildings_.size(); i++) {
|
int j;
|
||||||
for (j = 0; j < (int)gen_prefixes.size(); j++) {
|
for (j = 0; j < (int)gen_prefixes.size(); j++) {
|
||||||
String prefix = gen_prefixes[j];
|
String prefix = gen_prefixes[j];
|
||||||
if (buildings_[i].id.begins_with(prefix)) {
|
if (b.building.id.begins_with(prefix)) {
|
||||||
buildings_[i].generated = true;
|
b.building.generated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::load_data()
|
void BuildingsData::load_data()
|
||||||
@@ -334,16 +336,27 @@ void BuildingsData::checkpoint()
|
|||||||
{
|
{
|
||||||
struct checkpoint_data cp;
|
struct checkpoint_data cp;
|
||||||
cp.building_data = building_data;
|
cp.building_data = building_data;
|
||||||
cp.buildings = buildings_;
|
cp.buildings.clear();
|
||||||
|
ecs().each([&cp](flecs::entity e, const CBuildingData &b) {
|
||||||
|
cp.buildings.push_back(b.building);
|
||||||
|
});
|
||||||
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());
|
||||||
}
|
}
|
||||||
void BuildingsData::undo()
|
void BuildingsData::undo()
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
buildings_ = cp.buildings;
|
ecs().each([&cp](flecs::entity e, const CBuildingData &b) {
|
||||||
|
e.destruct();
|
||||||
|
});
|
||||||
|
for (i = 0; i < (int)cp.buildings.size(); i++) {
|
||||||
|
String ename = "base:" + cp.buildings[i].key;
|
||||||
|
flecs::entity e = ecs().entity(ename.ascii().ptr());
|
||||||
|
e.set<CBuildingData>({ cp.buildings[i] });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::fill_door_locations()
|
void BuildingsData::fill_door_locations()
|
||||||
@@ -424,43 +437,38 @@ func fill_door_locations():
|
|||||||
|
|
||||||
void BuildingsData::get_scene_keys_list(List<String> *keys) const
|
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) const
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
return e.is_valid();
|
return e.is_valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::remove_scene_item(const String &key, const String &bkey)
|
void BuildingsData::remove_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());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
flecs::query_builder<const CBuildingInstance> qb =
|
||||||
ecs.query_builder<const CBuildingInstance>().with(
|
ecs().query_builder<const CBuildingInstance>().with(
|
||||||
flecs::ChildOf, e);
|
flecs::ChildOf, e);
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
flecs::query<const CBuildingInstance> q = qb.build();
|
||||||
uint64_t key_hash = bkey.hash64();
|
uint64_t key_hash = bkey.hash64();
|
||||||
flecs::entity em = q.find([key_hash](const CBuildingInstance &bi) {
|
flecs::entity em = q.find([key_hash](const CBuildingInstance &bi) {
|
||||||
return bi.key.hash64() == key_hash;
|
return bi.key.hash64() == key_hash;
|
||||||
});
|
});
|
||||||
if (em.is_valid()) {
|
if (em.is_valid())
|
||||||
CBuildingInstance *bi = em.get_mut<CBuildingInstance>();
|
|
||||||
if (bi->node)
|
|
||||||
bi->node->queue_delete();
|
|
||||||
bi->node = nullptr;
|
|
||||||
em.destruct();
|
em.destruct();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
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());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
@@ -468,7 +476,7 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
|||||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||||
if (ce.is_valid())
|
if (ce.is_valid())
|
||||||
ce.destruct();
|
ce.destruct();
|
||||||
ce = ecs.entity(ename.ascii().ptr());
|
ce = ecs().entity(ename.ascii().ptr());
|
||||||
ce.child_of(e);
|
ce.child_of(e);
|
||||||
ce.set<CBuildingInstance>({ bkey, nullptr });
|
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||||
print_line("child name: " + String(ce.name()));
|
print_line("child name: " + String(ce.name()));
|
||||||
@@ -477,7 +485,7 @@ void BuildingsData::add_scene_item(const String &key, const String &bkey)
|
|||||||
void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
||||||
{
|
{
|
||||||
if (!has_scene(key)) {
|
if (!has_scene(key)) {
|
||||||
flecs::entity e = ecs.entity(key.ascii().ptr());
|
flecs::entity e = ecs().entity(key.ascii().ptr());
|
||||||
String path = building_data[key];
|
String path = building_data[key];
|
||||||
print_line("Requesting " + (bkey) + " " + path);
|
print_line("Requesting " + (bkey) + " " + path);
|
||||||
struct scene_data sd;
|
struct scene_data sd;
|
||||||
@@ -490,7 +498,7 @@ void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
|||||||
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
flecs::entity ce = e.lookup(ename.ascii().ptr());
|
||||||
if (ce.is_valid())
|
if (ce.is_valid())
|
||||||
ce.destruct();
|
ce.destruct();
|
||||||
ce = ecs.entity(ename.ascii().ptr());
|
ce = ecs().entity(ename.ascii().ptr());
|
||||||
ce.child_of(e);
|
ce.child_of(e);
|
||||||
ce.set<CBuildingInstance>({ bkey, nullptr });
|
ce.set<CBuildingInstance>({ bkey, nullptr });
|
||||||
print_line("child name: " + String(ce.name()));
|
print_line("child name: " + String(ce.name()));
|
||||||
@@ -499,7 +507,7 @@ void BuildingsData::create_scene_data(const String &key, const String &bkey)
|
|||||||
|
|
||||||
Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key) const
|
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.is_valid())
|
if (!e.is_valid())
|
||||||
return Ref<PackedScene>();
|
return Ref<PackedScene>();
|
||||||
if (!e.get<CSceneData>())
|
if (!e.get<CSceneData>())
|
||||||
@@ -512,7 +520,7 @@ Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key) const
|
|||||||
|
|
||||||
int BuildingsData::scene_get_item_count(const String &key) const
|
int BuildingsData::scene_get_item_count(const String &key) const
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
if (!e.is_valid())
|
if (!e.is_valid())
|
||||||
return 0;
|
return 0;
|
||||||
if (!e.get<CSceneData>())
|
if (!e.get<CSceneData>())
|
||||||
@@ -522,7 +530,7 @@ int BuildingsData::scene_get_item_count(const String &key) const
|
|||||||
assert(d);
|
assert(d);
|
||||||
// return d->sd.buildings.size();
|
// return d->sd.buildings.size();
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
flecs::query_builder<const CBuildingInstance> qb =
|
||||||
ecs.query_builder<const CBuildingInstance>().with(
|
ecs().query_builder<const CBuildingInstance>().with(
|
||||||
flecs::ChildOf, e);
|
flecs::ChildOf, e);
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
flecs::query<const CBuildingInstance> q = qb.build();
|
||||||
int result;
|
int result;
|
||||||
@@ -538,7 +546,7 @@ int BuildingsData::scene_get_item_count(const String &key) const
|
|||||||
List<String> BuildingsData::scene_get_items(const String &key) const
|
List<String> BuildingsData::scene_get_items(const String &key) const
|
||||||
{
|
{
|
||||||
List<String> ret;
|
List<String> ret;
|
||||||
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
if (!e.is_valid())
|
if (!e.is_valid())
|
||||||
return List<String>();
|
return List<String>();
|
||||||
if (!e.get<CSceneData>())
|
if (!e.get<CSceneData>())
|
||||||
@@ -547,7 +555,7 @@ List<String> BuildingsData::scene_get_items(const String &key) const
|
|||||||
const CSceneData *d = e.get<CSceneData>();
|
const CSceneData *d = e.get<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
flecs::query_builder<const CBuildingInstance> qb =
|
||||||
ecs.query_builder<const CBuildingInstance>().with(
|
ecs().query_builder<const CBuildingInstance>().with(
|
||||||
flecs::ChildOf, e);
|
flecs::ChildOf, e);
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
flecs::query<const CBuildingInstance> q = qb.build();
|
||||||
q.each([&ret](flecs::entity me, const CBuildingInstance &ib) {
|
q.each([&ret](flecs::entity me, const CBuildingInstance &ib) {
|
||||||
@@ -558,7 +566,7 @@ List<String> BuildingsData::scene_get_items(const String &key) const
|
|||||||
void BuildingsData::set_scene_item_node(const String &key, const String &bkey,
|
void BuildingsData::set_scene_item_node(const String &key, const String &bkey,
|
||||||
Node *node)
|
Node *node)
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
assert(e.is_valid());
|
assert(e.is_valid());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
@@ -572,7 +580,7 @@ void BuildingsData::set_scene_item_node(const String &key, const String &bkey,
|
|||||||
}
|
}
|
||||||
bool BuildingsData::has_scene_item(const String &key, const String &bkey) const
|
bool BuildingsData::has_scene_item(const String &key, 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());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
@@ -583,7 +591,7 @@ bool BuildingsData::has_scene_item(const String &key, const String &bkey) const
|
|||||||
Node *BuildingsData::get_scene_item_node(const String &key,
|
Node *BuildingsData::get_scene_item_node(const String &key,
|
||||||
const String &bkey) const
|
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());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
@@ -595,52 +603,11 @@ Node *BuildingsData::get_scene_item_node(const String &key,
|
|||||||
assert(bi->key == bkey);
|
assert(bi->key == bkey);
|
||||||
return bi->node;
|
return bi->node;
|
||||||
}
|
}
|
||||||
void BuildingsData::item_nodes_delete_node(const String &key)
|
|
||||||
{
|
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
|
||||||
ecs.query_builder<const CBuildingInstance>();
|
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
|
||||||
uint64_t key_hash = key.hash64();
|
|
||||||
flecs::entity e = q.find(
|
|
||||||
[key_hash](flecs::entity me, const CBuildingInstance &ib) {
|
|
||||||
return ib.key.hash64() == key_hash;
|
|
||||||
});
|
|
||||||
assert(e.is_valid());
|
|
||||||
CBuildingInstance *ib = e.get_mut<CBuildingInstance>();
|
|
||||||
if (ib->node)
|
|
||||||
ib->node->queue_delete();
|
|
||||||
ib->node = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingsData::item_nodes_item_removed(const String &key)
|
|
||||||
{
|
|
||||||
/* FIXME: pretty sure this is redundant */
|
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
|
||||||
ecs.query_builder<const CBuildingInstance>();
|
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
|
||||||
uint64_t key_hash = key.hash64();
|
|
||||||
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
|
|
||||||
return bi.key.hash64() == key_hash;
|
|
||||||
});
|
|
||||||
if (!e.is_valid())
|
|
||||||
return;
|
|
||||||
CBuildingInstance *bi = e.get_mut<CBuildingInstance>();
|
|
||||||
assert(bi);
|
|
||||||
if (bi->node) {
|
|
||||||
bi->node->queue_delete();
|
|
||||||
}
|
|
||||||
bi->node = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
String BuildingsData::item_nodes_get_key(int item) const
|
|
||||||
{
|
|
||||||
return buildings_[item].key;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *BuildingsData::item_nodes_get_node(const String &key) const
|
Node *BuildingsData::item_nodes_get_node(const String &key) const
|
||||||
{
|
{
|
||||||
flecs::query_builder<const CBuildingInstance> qb =
|
flecs::query_builder<const CBuildingInstance> qb =
|
||||||
ecs.query_builder<const CBuildingInstance>();
|
ecs().query_builder<const CBuildingInstance>();
|
||||||
flecs::query<const CBuildingInstance> q = qb.build();
|
flecs::query<const CBuildingInstance> q = qb.build();
|
||||||
uint64_t key_hash = key.hash64();
|
uint64_t key_hash = key.hash64();
|
||||||
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
|
flecs::entity e = q.find([key_hash](const CBuildingInstance &bi) {
|
||||||
@@ -655,7 +622,7 @@ Node *BuildingsData::item_nodes_get_node(const String &key) const
|
|||||||
Error BuildingsData::scene_loader_poll(const String &key)
|
Error BuildingsData::scene_loader_poll(const String &key)
|
||||||
{
|
{
|
||||||
if (has_scene(key)) {
|
if (has_scene(key)) {
|
||||||
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
flecs::entity e = ecs().lookup(key.ascii().ptr());
|
||||||
assert(e.is_valid());
|
assert(e.is_valid());
|
||||||
CSceneData *d = e.get_mut<CSceneData>();
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
assert(d);
|
assert(d);
|
||||||
@@ -692,23 +659,35 @@ void BuildingsData::scene_update()
|
|||||||
|
|
||||||
int BuildingsData::get_building_count() const
|
int BuildingsData::get_building_count() const
|
||||||
{
|
{
|
||||||
return buildings_.size();
|
flecs::query<const CBuildingData> q =
|
||||||
|
ecs().query<const CBuildingData>();
|
||||||
|
int result;
|
||||||
|
q.run([&result](flecs::iter &it) {
|
||||||
|
it.next();
|
||||||
|
result = it.count();
|
||||||
|
it.fini();
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct BuildingsData::building &
|
const struct BuildingsData::building &
|
||||||
BuildingsData::get_building(const String &building_key) const
|
BuildingsData::get_building(const String &building_key) const
|
||||||
{
|
{
|
||||||
int index = get_building_by_key(building_key);
|
String ename = "base:" + building_key;
|
||||||
assert(index >= 0 && index < get_building_count());
|
print_line("get_building: " + ename);
|
||||||
return buildings_[index];
|
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)
|
||||||
{
|
{
|
||||||
int index = get_building_by_key(building_key);
|
String ename = "base:" + building_key;
|
||||||
assert(index >= 0 && index < get_building_count());
|
print_line("get_building: " + ename);
|
||||||
return buildings_[index];
|
flecs::entity e = lookup(ename);
|
||||||
|
assert(e.is_valid());
|
||||||
|
return e.get_mut<CBuildingData>()->building;
|
||||||
}
|
}
|
||||||
|
|
||||||
String BuildingsData::create_building(const Dictionary &dict)
|
String BuildingsData::create_building(const Dictionary &dict)
|
||||||
@@ -721,39 +700,37 @@ String BuildingsData::create_building(const Dictionary &dict)
|
|||||||
String BuildingsData::create_building(const struct building &building)
|
String BuildingsData::create_building(const struct building &building)
|
||||||
{
|
{
|
||||||
assert(building.key.length() > 0);
|
assert(building.key.length() > 0);
|
||||||
buildings_.push_back(building);
|
String ename = "base:" + building.key;
|
||||||
|
print_line("create_building: " + ename);
|
||||||
|
flecs::entity e = ecs().lookup(ename.ascii().ptr());
|
||||||
|
assert(!e.is_valid());
|
||||||
|
e = ecs().entity(ename.ascii().ptr());
|
||||||
|
e.set<CBuildingData>({ building });
|
||||||
|
assert(e.is_valid());
|
||||||
|
print_line("create_building: " + ename + " created");
|
||||||
|
|
||||||
return building.key;
|
return building.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::for_each_building(callme &c)
|
void BuildingsData::for_each_building(struct callme &c)
|
||||||
{
|
{
|
||||||
List<String> keys;
|
ecs().each([&c](const CBuildingData &b) { c(b.building.key); });
|
||||||
get_building_keys_list(&keys);
|
|
||||||
List<String>::Element *e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
c(e->get());
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::for_each_building(void (*func)(const String &key,
|
void BuildingsData::for_each_building(void (*func)(const String &key,
|
||||||
void *data),
|
void *data),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
List<String> keys;
|
ecs().each([func, data](const CBuildingData &b) {
|
||||||
get_building_keys_list(&keys);
|
func(b.building.key, data);
|
||||||
List<String>::Element *e = keys.front();
|
});
|
||||||
while (e) {
|
|
||||||
func(e->get(), data);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingsData::get_building_keys_list(List<String> *keys)
|
void BuildingsData::get_building_keys_list(List<String> *keys)
|
||||||
{
|
{
|
||||||
int i;
|
ecs().each([keys](const CBuildingData &e) {
|
||||||
for (i = 0; i < get_building_count(); i++)
|
keys->push_back(e.building.key);
|
||||||
keys->push_back(buildings_[i].key);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
String BuildingsData::create_building(const building *building)
|
String BuildingsData::create_building(const building *building)
|
||||||
@@ -764,8 +741,12 @@ String BuildingsData::create_building(const building *building)
|
|||||||
|
|
||||||
bool BuildingsData::destroy_building(const String &key)
|
bool BuildingsData::destroy_building(const String &key)
|
||||||
{
|
{
|
||||||
int index = get_building_by_key(key);
|
assert(key.length() > 0);
|
||||||
assert(index >= 0 && index < get_building_count());
|
String ename = "base:" + key;
|
||||||
buildings_.erase(buildings_.begin() + index);
|
print_line("destroy_building: " + ename);
|
||||||
|
flecs::entity e = ecs().lookup(ename.ascii().ptr());
|
||||||
|
assert(e.is_valid());
|
||||||
|
e.destruct();
|
||||||
|
print_line("destroy_building: " + ename + " destroyed");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,9 @@ public:
|
|||||||
Node *get_scene_item_node(const String &key, const String &bkey) const;
|
Node *get_scene_item_node(const String &key, const String &bkey) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void item_nodes_delete_node(const String &key);
|
|
||||||
// bool item_nodes_exists(const String &key) const;
|
|
||||||
// void item_nodes_set_node(const String &key, Node *node);
|
|
||||||
void item_nodes_item_removed(const String &key);
|
|
||||||
Node *item_nodes_get_node(const String &key) const;
|
Node *item_nodes_get_node(const String &key) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String item_nodes_get_key(int item) const;
|
|
||||||
Error scene_loader_poll(const String &key);
|
Error scene_loader_poll(const String &key);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -57,9 +52,6 @@ public:
|
|||||||
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;
|
||||||
/* Data for each building in a world */
|
|
||||||
private:
|
|
||||||
std::vector<struct building> buildings_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct building &get_building(const String &building_key);
|
struct building &get_building(const String &building_key);
|
||||||
@@ -138,8 +130,5 @@ public:
|
|||||||
String get_closest_building(const Transform &xform);
|
String get_closest_building(const Transform &xform);
|
||||||
static BuildingsData *get_singleton();
|
static BuildingsData *get_singleton();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
|
||||||
private:
|
|
||||||
int get_building_by_key(const String &key) const;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -15,6 +15,54 @@
|
|||||||
#include "editor_event.h"
|
#include "editor_event.h"
|
||||||
#include "road_lines_data.h"
|
#include "road_lines_data.h"
|
||||||
|
|
||||||
|
class LinesAccessor {
|
||||||
|
HashMap<String, struct RoadLinesData::road_line> lines_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline const struct RoadLinesData::road_line &
|
||||||
|
get_line(const String &key) const
|
||||||
|
{
|
||||||
|
return lines_[key];
|
||||||
|
}
|
||||||
|
inline const struct RoadLinesData::road_line *
|
||||||
|
get_line_ptr(const String &key) const
|
||||||
|
{
|
||||||
|
return &lines_[key];
|
||||||
|
}
|
||||||
|
inline struct RoadLinesData::road_line &get_line(const String &key)
|
||||||
|
{
|
||||||
|
return lines_[key];
|
||||||
|
}
|
||||||
|
inline const struct RoadLinesData::road_line &
|
||||||
|
operator[](const String &key) const
|
||||||
|
{
|
||||||
|
return lines_[key];
|
||||||
|
}
|
||||||
|
inline struct RoadLinesData::road_line &operator[](const String &key)
|
||||||
|
{
|
||||||
|
return lines_[key];
|
||||||
|
}
|
||||||
|
inline bool has(const String &key)
|
||||||
|
{
|
||||||
|
return lines_.has(key);
|
||||||
|
}
|
||||||
|
void get_key_list(List<String> *keys)
|
||||||
|
{
|
||||||
|
lines_.get_key_list(keys);
|
||||||
|
}
|
||||||
|
const String &get_next(const String &key)
|
||||||
|
{
|
||||||
|
const String *r = lines_.next(&key);
|
||||||
|
return *r;
|
||||||
|
}
|
||||||
|
void erase(const String &key)
|
||||||
|
{
|
||||||
|
lines_.erase(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static LinesAccessor lines;
|
||||||
|
|
||||||
ImmediateGeometry *RoadLinesData::debug_im = nullptr;
|
ImmediateGeometry *RoadLinesData::debug_im = nullptr;
|
||||||
static Ref<Material> debug_material;
|
static Ref<Material> debug_material;
|
||||||
RoadLinesData::RoadLinesData()
|
RoadLinesData::RoadLinesData()
|
||||||
@@ -22,6 +70,27 @@ RoadLinesData::RoadLinesData()
|
|||||||
load_data();
|
load_data();
|
||||||
}
|
}
|
||||||
RoadLinesData *RoadLinesData::singleton = nullptr;
|
RoadLinesData *RoadLinesData::singleton = nullptr;
|
||||||
|
const struct RoadLinesData::road_line &
|
||||||
|
RoadLinesData::get_line(const String &key) const
|
||||||
|
{
|
||||||
|
return ::lines[key];
|
||||||
|
}
|
||||||
|
struct RoadLinesData::road_line &RoadLinesData::get_line(const String &key)
|
||||||
|
{
|
||||||
|
return ::lines[key];
|
||||||
|
}
|
||||||
|
const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const
|
||||||
|
{
|
||||||
|
return ::lines[key];
|
||||||
|
}
|
||||||
|
RoadLinesData::road_line &RoadLinesData::lines(const String &key)
|
||||||
|
{
|
||||||
|
return ::lines[key];
|
||||||
|
}
|
||||||
|
bool RoadLinesData::has_line(const String &key)
|
||||||
|
{
|
||||||
|
return ::lines.has(key);
|
||||||
|
}
|
||||||
RoadLinesData *RoadLinesData::get_singleton()
|
RoadLinesData *RoadLinesData::get_singleton()
|
||||||
{
|
{
|
||||||
if (!singleton)
|
if (!singleton)
|
||||||
@@ -49,7 +118,7 @@ String RoadLinesData::get_road_lines_path()
|
|||||||
void RoadLinesData::get_road_lines_key_list(List<String> *keys)
|
void RoadLinesData::get_road_lines_key_list(List<String> *keys)
|
||||||
{
|
{
|
||||||
List<String> line_keys;
|
List<String> line_keys;
|
||||||
lines.get_key_list(&line_keys);
|
::lines.get_key_list(&line_keys);
|
||||||
List<String>::Element *e = line_keys.front();
|
List<String>::Element *e = line_keys.front();
|
||||||
keys->clear();
|
keys->clear();
|
||||||
while (e) {
|
while (e) {
|
||||||
@@ -59,6 +128,18 @@ void RoadLinesData::get_road_lines_key_list(List<String> *keys)
|
|||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void RoadLinesData::get_lines_key_list(List<String> *keys)
|
||||||
|
{
|
||||||
|
::lines.get_key_list(keys);
|
||||||
|
}
|
||||||
|
const String &RoadLinesData::get_next_line(const String &key)
|
||||||
|
{
|
||||||
|
return ::lines.get_next(key);
|
||||||
|
}
|
||||||
|
void RoadLinesData::erase_line(const String &key)
|
||||||
|
{
|
||||||
|
return ::lines.erase(key);
|
||||||
|
}
|
||||||
void RoadLinesData::load_data()
|
void RoadLinesData::load_data()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -109,7 +190,7 @@ void RoadLinesData::load_data()
|
|||||||
}
|
}
|
||||||
// TODO: wtf is flags?
|
// TODO: wtf is flags?
|
||||||
rline.lanes = lanes;
|
rline.lanes = lanes;
|
||||||
lines[key] = rline;
|
lines(key) = rline;
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,26 +205,26 @@ void RoadLinesData::save_data()
|
|||||||
FileAccess::get_file_as_string(road_lines_path);
|
FileAccess::get_file_as_string(road_lines_path);
|
||||||
Dictionary output;
|
Dictionary output;
|
||||||
List<String> keys;
|
List<String> keys;
|
||||||
lines.get_key_list(&keys);
|
::lines.get_key_list(&keys);
|
||||||
List<String>::Element *e = keys.front();
|
List<String>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
Dictionary pvalues;
|
Dictionary pvalues;
|
||||||
Array points, indices;
|
Array points, indices;
|
||||||
points.resize(lines[e->get()].points.size());
|
points.resize(lines(e->get()).points.size());
|
||||||
for (i = 0; i < (int)lines[e->get()].points.size(); i++)
|
for (i = 0; i < (int)lines(e->get()).points.size(); i++)
|
||||||
points[i] = to_string(lines[e->get()].points[i]);
|
points[i] = to_string(lines(e->get()).points[i]);
|
||||||
indices.resize(lines[e->get()].indices.size());
|
indices.resize(lines(e->get()).indices.size());
|
||||||
for (i = 0; i < (int)lines[e->get()].indices.size(); i++)
|
for (i = 0; i < (int)lines(e->get()).indices.size(); i++)
|
||||||
indices[i] = lines[e->get()].indices[i];
|
indices[i] = lines(e->get()).indices[i];
|
||||||
pvalues["points"] = points;
|
pvalues["points"] = points;
|
||||||
// pvalues["indices"] = indices;
|
// pvalues["indices"] = indices;
|
||||||
pvalues["metadata"] = lines[e->get()].metadata;
|
pvalues["metadata"] = lines(e->get()).metadata;
|
||||||
pvalues["lanes"] = lines[e->get()].lanes;
|
pvalues["lanes"] = lines(e->get()).lanes;
|
||||||
pvalues["pattern"] = lines[e->get()].pattern;
|
pvalues["pattern"] = ::lines[e->get()].pattern;
|
||||||
Array buildings;
|
Array buildings;
|
||||||
for (i = 0; i < (int)lines[e->get()].buildings.size(); i++)
|
for (i = 0; i < (int)::lines[e->get()].buildings.size(); i++)
|
||||||
buildings.push_back(
|
buildings.push_back(
|
||||||
lines[e->get()].buildings[i].to_dict());
|
::lines[e->get()].buildings[i].to_dict());
|
||||||
pvalues["buildings"] = buildings;
|
pvalues["buildings"] = buildings;
|
||||||
output[e->get()] = pvalues;
|
output[e->get()] = pvalues;
|
||||||
e = e->next();
|
e = e->next();
|
||||||
@@ -224,14 +305,14 @@ void RoadLinesData::index_lines(
|
|||||||
List<String>::Element *e = keys.front();
|
List<String>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
String rkey = e->get();
|
String rkey = e->get();
|
||||||
struct RoadLinesData::road_line &pt = lines[rkey];
|
struct RoadLinesData::road_line &pt = ::lines[rkey];
|
||||||
pt.indices.clear();
|
pt.indices.clear();
|
||||||
e = e->next();
|
e = e->next();
|
||||||
}
|
}
|
||||||
e = keys.front();
|
e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
String rkey = e->get();
|
String rkey = e->get();
|
||||||
struct RoadLinesData::road_line &pt = lines[rkey];
|
struct RoadLinesData::road_line &pt = ::lines[rkey];
|
||||||
road_lines_curve_index(pt, road_lines_nodes_hash,
|
road_lines_curve_index(pt, road_lines_nodes_hash,
|
||||||
road_lines_nodes);
|
road_lines_nodes);
|
||||||
e = e->next();
|
e = e->next();
|
||||||
@@ -240,14 +321,14 @@ void RoadLinesData::index_lines(
|
|||||||
static inline int get_segment_index(const String &road, int pos)
|
static inline int get_segment_index(const String &road, int pos)
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
int idx = rld->lines[road].indices[pos];
|
int idx = rld->get_line(road).indices[pos];
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
void RoadLinesData::create_segments(const String &road,
|
void RoadLinesData::create_segments(const String &road,
|
||||||
std::vector<int> &segments)
|
std::vector<int> &segments)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < (int)lines[road].indices.size() - 1; i++) {
|
for (i = 0; i < (int)::lines[road].indices.size() - 1; i++) {
|
||||||
segments.push_back(i);
|
segments.push_back(i);
|
||||||
segments.push_back(i + 1);
|
segments.push_back(i + 1);
|
||||||
}
|
}
|
||||||
@@ -297,8 +378,8 @@ void RoadLinesData::insert_close_points(std::vector<Vector3> &road_lines_nodes,
|
|||||||
distance_squared) {
|
distance_squared) {
|
||||||
/* split segment and replace road
|
/* split segment and replace road
|
||||||
point with a point on segment */
|
point with a point on segment */
|
||||||
lines[rkey].indices.insert(
|
::lines[rkey].indices.insert(
|
||||||
lines[rkey].indices.begin() +
|
::lines[rkey].indices.begin() +
|
||||||
idx,
|
idx,
|
||||||
idx3);
|
idx3);
|
||||||
road_lines_nodes[idx3] = closest;
|
road_lines_nodes[idx3] = closest;
|
||||||
@@ -345,22 +426,23 @@ void RoadLinesData::update_road_lines_nodes(
|
|||||||
std::tuple<String, String> data = kcmp[it->first];
|
std::tuple<String, String> data = kcmp[it->first];
|
||||||
const String &k = std::get<0>(data);
|
const String &k = std::get<0>(data);
|
||||||
const String &r = std::get<1>(data);
|
const String &r = std::get<1>(data);
|
||||||
if (lines[k].indices.size() < 2)
|
if (::lines[k].indices.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
if (lines[r].indices.size() < 2)
|
if (::lines[r].indices.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
for (i = 0; i < (int)lines[k].indices.size() - 1; i++) {
|
for (i = 0; i < (int)::lines[k].indices.size() - 1; i++) {
|
||||||
for (j = 0; j < (int)lines[k].indices.size() - 1; j++) {
|
for (j = 0; j < (int)::lines[k].indices.size() - 1;
|
||||||
|
j++) {
|
||||||
uint32_t key = k.hash() ^ i ^ r.hash() ^ j ^
|
uint32_t key = k.hash() ^ i ^ r.hash() ^ j ^
|
||||||
2147483137;
|
2147483137;
|
||||||
uint32_t key2 = r.hash() ^ j ^ k.hash() ^ i ^
|
uint32_t key2 = r.hash() ^ j ^ k.hash() ^ i ^
|
||||||
2147463167;
|
2147463167;
|
||||||
if (checks.find(key) == checks.end() &&
|
if (checks.find(key) == checks.end() &&
|
||||||
checks.find(key2) == checks.end()) {
|
checks.find(key2) == checks.end()) {
|
||||||
int idx_a1 = lines[k].indices[i];
|
int idx_a1 = ::lines[k].indices[i];
|
||||||
int idx_a2 = lines[k].indices[i + 1];
|
int idx_a2 = ::lines[k].indices[i + 1];
|
||||||
int idx_b1 = lines[k].indices[j];
|
int idx_b1 = ::lines[k].indices[j];
|
||||||
int idx_b2 = lines[k].indices[j + 1];
|
int idx_b2 = ::lines[k].indices[j + 1];
|
||||||
std::vector<int> cmp1 = { idx_a1,
|
std::vector<int> cmp1 = { idx_a1,
|
||||||
idx_a2 };
|
idx_a2 };
|
||||||
if (std::find(cmp1.begin(), cmp1.end(),
|
if (std::find(cmp1.begin(), cmp1.end(),
|
||||||
@@ -426,16 +508,16 @@ void RoadLinesData::update_road_lines_nodes(
|
|||||||
int nidx = road_lines_nodes.size();
|
int nidx = road_lines_nodes.size();
|
||||||
road_lines_nodes.push_back(pxt);
|
road_lines_nodes.push_back(pxt);
|
||||||
// int il = (int)road_lines[k].indices.size();
|
// int il = (int)road_lines[k].indices.size();
|
||||||
assert(std::find(lines[k].indices.begin(),
|
assert(std::find(::lines[k].indices.begin(),
|
||||||
lines[k].indices.end(),
|
::lines[k].indices.end(),
|
||||||
nidx) == lines[k].indices.end());
|
nidx) == ::lines[k].indices.end());
|
||||||
assert(std::find(lines[r].indices.begin(),
|
assert(std::find(::lines[r].indices.begin(),
|
||||||
lines[r].indices.end(),
|
::lines[r].indices.end(),
|
||||||
nidx) == lines[r].indices.end());
|
nidx) == ::lines[r].indices.end());
|
||||||
lines[k].indices.insert(
|
::lines[k].indices.insert(
|
||||||
lines[k].indices.begin() + i + 1, nidx);
|
::lines[k].indices.begin() + i + 1, nidx);
|
||||||
lines[r].indices.insert(
|
::lines[r].indices.insert(
|
||||||
lines[k].indices.begin() + j + 1, nidx);
|
::lines[k].indices.begin() + j + 1, nidx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,7 +529,7 @@ void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes
|
|||||||
List<String>::Element *e = keys.front();
|
List<String>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
String rkey = e->get();
|
String rkey = e->get();
|
||||||
struct RoadLinesData::road_line &pt = lines[rkey];
|
struct RoadLinesData::road_line &pt = ::lines[rkey];
|
||||||
String outline = rkey + ": ";
|
String outline = rkey + ": ";
|
||||||
for (i = 0; i < (int)pt.indices.size(); i++) {
|
for (i = 0; i < (int)pt.indices.size(); i++) {
|
||||||
outline += " " + itos(pt.indices[i]);
|
outline += " " + itos(pt.indices[i]);
|
||||||
@@ -501,20 +583,20 @@ int RoadLinesData::get_debug_flags() const
|
|||||||
void RoadLinesData::update_line_segments(const String &line)
|
void RoadLinesData::update_line_segments(const String &line)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
lines[line].segments.clear();
|
::lines[line].segments.clear();
|
||||||
lines[line].segments.resize(lines[line].points.size() - 1);
|
::lines[line].segments.resize(::lines[line].points.size() - 1);
|
||||||
float offset = 0.0f;
|
float offset = 0.0f;
|
||||||
for (i = 0; i < (int)lines[line].points.size() - 1; i++) {
|
for (i = 0; i < (int)::lines[line].points.size() - 1; i++) {
|
||||||
struct line_segment segment;
|
struct line_segment segment;
|
||||||
segment.p1 = lines[line].points[i].origin;
|
segment.p1 = ::lines[line].points[i].origin;
|
||||||
segment.p2 = lines[line].points[i + 1].origin;
|
segment.p2 = ::lines[line].points[i + 1].origin;
|
||||||
segment.length = segment.p1.distance_to(segment.p2);
|
segment.length = segment.p1.distance_to(segment.p2);
|
||||||
segment.dir = (segment.p2 - segment.p1).normalized();
|
segment.dir = (segment.p2 - segment.p1).normalized();
|
||||||
Vector3 side = segment.dir.cross(Vector3(0, 1, 0));
|
Vector3 side = segment.dir.cross(Vector3(0, 1, 0));
|
||||||
side.y = 0;
|
side.y = 0;
|
||||||
segment.tangent = side.normalized();
|
segment.tangent = side.normalized();
|
||||||
segment.offset = offset;
|
segment.offset = offset;
|
||||||
lines[line].segments[i] = segment;
|
::lines[line].segments[i] = segment;
|
||||||
offset += segment.length;
|
offset += segment.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,7 +611,7 @@ void RoadLinesData::line_add_building(const String &line, const String &key,
|
|||||||
lb.line_offset = curve_offset;
|
lb.line_offset = curve_offset;
|
||||||
lb.normal_offset = normal_offset;
|
lb.normal_offset = normal_offset;
|
||||||
lb.y_rotation = y_rotation;
|
lb.y_rotation = y_rotation;
|
||||||
lines[line].buildings.push_back(lb);
|
::lines[line].buildings.push_back(lb);
|
||||||
// TODO: save/load
|
// TODO: save/load
|
||||||
BuildingsData::get_singleton()->get_building(key).line_name = line;
|
BuildingsData::get_singleton()->get_building(key).line_name = line;
|
||||||
}
|
}
|
||||||
@@ -538,14 +620,14 @@ void RoadLinesData::assign_close_buildings(const String &line)
|
|||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
print_line("assign_close_buildings: " + line);
|
print_line("assign_close_buildings: " + line);
|
||||||
if (!lines.has(line))
|
if (!::lines.has(line))
|
||||||
return;
|
return;
|
||||||
if (!line.ends_with("_buildings"))
|
if (!line.ends_with("_buildings"))
|
||||||
return;
|
return;
|
||||||
if (lines[line].points.size() < 2)
|
if (::lines[line].points.size() < 2)
|
||||||
return;
|
return;
|
||||||
update_line_segments(line);
|
update_line_segments(line);
|
||||||
if (lines[line].segments.size() == 0)
|
if (::lines[line].segments.size() == 0)
|
||||||
return;
|
return;
|
||||||
print_line("assign_close_buildings: processing: " +
|
print_line("assign_close_buildings: processing: " +
|
||||||
itos(BuildingsData::get_singleton()->get_building_count()) +
|
itos(BuildingsData::get_singleton()->get_building_count()) +
|
||||||
@@ -577,21 +659,22 @@ void RoadLinesData::assign_close_buildings(const String &line)
|
|||||||
Vector3 segment_point;
|
Vector3 segment_point;
|
||||||
int segment_index = -1;
|
int segment_index = -1;
|
||||||
|
|
||||||
for (j = 0; j < (int)lines[line].segments.size(); j++) {
|
for (j = 0; j < (int)::lines[line].segments.size(); j++) {
|
||||||
Vector3 seg[] = { lines[line].segments[j].p1,
|
Vector3 seg[] = { ::lines[line].segments[j].p1,
|
||||||
lines[line].segments[j].p2 };
|
::lines[line].segments[j].p2 };
|
||||||
Vector3 closest =
|
Vector3 closest =
|
||||||
Geometry::get_closest_point_to_segment(p, seg);
|
Geometry::get_closest_point_to_segment(p, seg);
|
||||||
Vector3 xp = p;
|
Vector3 xp = p;
|
||||||
xp.y = p.y;
|
xp.y = p.y;
|
||||||
float tmpdst = xp.distance_squared_to(closest);
|
float tmpdst = xp.distance_squared_to(closest);
|
||||||
if (closest.is_equal_approx(
|
if (closest.is_equal_approx(
|
||||||
lines[line].segments[j].p1) ||
|
::lines[line].segments[j].p1) ||
|
||||||
closest.is_equal_approx(
|
closest.is_equal_approx(
|
||||||
lines[line].segments[j].p2)) {
|
::lines[line].segments[j].p2)) {
|
||||||
float w = closest.dot(
|
float w = closest.dot(
|
||||||
lines[line].segments[j].dir);
|
::lines[line].segments[j].dir);
|
||||||
float wt = xp.dot(lines[line].segments[j].dir);
|
float wt =
|
||||||
|
xp.dot(::lines[line].segments[j].dir);
|
||||||
if (wt - w > 0.1f || wt - w < -0.1f)
|
if (wt - w > 0.1f || wt - w < -0.1f)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -605,9 +688,9 @@ void RoadLinesData::assign_close_buildings(const String &line)
|
|||||||
if (segment_index < 0)
|
if (segment_index < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Vector3 &p1 = lines[line].segments[segment_index].p1;
|
const Vector3 &p1 = ::lines[line].segments[segment_index].p1;
|
||||||
const Vector3 &p2 = lines[line].segments[segment_index].p2;
|
const Vector3 &p2 = ::lines[line].segments[segment_index].p2;
|
||||||
const Vector3 &dir = lines[line].segments[segment_index].dir;
|
const Vector3 &dir = ::lines[line].segments[segment_index].dir;
|
||||||
assert(segment_index >= 0);
|
assert(segment_index >= 0);
|
||||||
// assert(!segment_point.is_equal_approx(p1));
|
// assert(!segment_point.is_equal_approx(p1));
|
||||||
// assert(!segment_point.is_equal_approx(p2));
|
// assert(!segment_point.is_equal_approx(p2));
|
||||||
@@ -616,8 +699,8 @@ void RoadLinesData::assign_close_buildings(const String &line)
|
|||||||
print_line("wdst=" + String::num(wdst));
|
print_line("wdst=" + String::num(wdst));
|
||||||
assert(wdst >= 0);
|
assert(wdst >= 0);
|
||||||
result_offset =
|
result_offset =
|
||||||
lines[line].segments[segment_index].offset + wdst;
|
::lines[line].segments[segment_index].offset + wdst;
|
||||||
side = (p - p1).dot(lines[line].segments[j].tangent);
|
side = (p - p1).dot(::lines[line].segments[j].tangent);
|
||||||
|
|
||||||
assert(result_offset >= 0);
|
assert(result_offset >= 0);
|
||||||
|
|
||||||
@@ -645,8 +728,8 @@ bool RoadLinesData::line_has_building(const String &line,
|
|||||||
uint64_t key_hash = building_key.hash64();
|
uint64_t key_hash = building_key.hash64();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < (int)lines[line].buildings.size(); i++)
|
for (i = 0; i < (int)::lines[line].buildings.size(); i++)
|
||||||
if (lines[line].buildings[i].building_key_hash == key_hash) {
|
if (::lines[line].buildings[i].building_key_hash == key_hash) {
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -659,14 +742,14 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line,
|
|||||||
{
|
{
|
||||||
Vector3 ret;
|
Vector3 ret;
|
||||||
int i;
|
int i;
|
||||||
assert(lines.has(line));
|
assert(::lines.has(line));
|
||||||
print_verbose("line: " + line +
|
print_verbose("line: " + line +
|
||||||
" line_offset: " + String::num(dir_offset) +
|
" line_offset: " + String::num(dir_offset) +
|
||||||
" normal_offset: " + String::num(normal_offset));
|
" normal_offset: " + String::num(normal_offset));
|
||||||
float n_offset = dir_offset;
|
float n_offset = dir_offset;
|
||||||
int selected_segment = 0;
|
int selected_segment = 0;
|
||||||
for (i = 0; i < (int)lines[line].segments.size(); i++) {
|
for (i = 0; i < (int)::lines[line].segments.size(); i++) {
|
||||||
struct line_segment *segment = &lines[line].segments[i];
|
struct line_segment *segment = &::lines[line].segments[i];
|
||||||
if (n_offset < segment->length) {
|
if (n_offset < segment->length) {
|
||||||
selected_segment = i;
|
selected_segment = i;
|
||||||
break;
|
break;
|
||||||
@@ -674,9 +757,9 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line,
|
|||||||
n_offset -= segment->length;
|
n_offset -= segment->length;
|
||||||
}
|
}
|
||||||
print_verbose("offset: " + String::num(n_offset));
|
print_verbose("offset: " + String::num(n_offset));
|
||||||
ret = lines[line].segments[selected_segment].p1 +
|
ret = ::lines[line].segments[selected_segment].p1 +
|
||||||
lines[line].segments[selected_segment].dir * n_offset +
|
::lines[line].segments[selected_segment].dir * n_offset +
|
||||||
lines[line].segments[selected_segment].tangent * normal_offset;
|
::lines[line].segments[selected_segment].tangent * normal_offset;
|
||||||
print_verbose("data: " + (ret.operator String()));
|
print_verbose("data: " + (ret.operator String()));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -685,46 +768,50 @@ void RoadLinesData::update_buildings_from_lines()
|
|||||||
{
|
{
|
||||||
BuildingsData *bd = BuildingsData::get_singleton();
|
BuildingsData *bd = BuildingsData::get_singleton();
|
||||||
List<String> keys;
|
List<String> keys;
|
||||||
lines.get_key_list(&keys);
|
::lines.get_key_list(&keys);
|
||||||
List<String>::Element *e = keys.front();
|
List<String>::Element *e = keys.front();
|
||||||
while (e) {
|
while (e) {
|
||||||
int i;
|
int i;
|
||||||
const String &line = e->get();
|
const String &line = e->get();
|
||||||
for (i = 0; i < (int)lines[line].buildings.size(); i++) {
|
for (i = 0; i < (int)::lines[line].buildings.size(); i++) {
|
||||||
const uint64_t &building_key_hash =
|
const uint64_t &building_key_hash =
|
||||||
lines[line].buildings[i].building_key_hash;
|
::lines[line].buildings[i].building_key_hash;
|
||||||
bool found = bd->has_building(
|
bool found = bd->has_building(
|
||||||
lines[line].buildings[i].building_key);
|
::lines[line].buildings[i].building_key);
|
||||||
if (found) {
|
if (found) {
|
||||||
struct BuildingsData::building &b =
|
struct BuildingsData::building &b =
|
||||||
bd->get_building(lines[line]
|
bd->get_building(::lines[line]
|
||||||
.buildings[i]
|
.buildings[i]
|
||||||
.building_key);
|
.building_key);
|
||||||
Vector3 pt = get_point_by_offsets(
|
Vector3 pt = get_point_by_offsets(
|
||||||
line,
|
line,
|
||||||
lines[line].buildings[i].line_offset,
|
::lines[line].buildings[i].line_offset,
|
||||||
lines[line].buildings[i].normal_offset);
|
::lines[line]
|
||||||
|
.buildings[i]
|
||||||
|
.normal_offset);
|
||||||
Basis basis = Basis().rotated(
|
Basis basis = Basis().rotated(
|
||||||
Vector3(0, 1, 0),
|
Vector3(0, 1, 0),
|
||||||
lines[line].buildings[i].y_rotation);
|
::lines[line].buildings[i].y_rotation);
|
||||||
b.xform.origin = pt;
|
b.xform.origin = pt;
|
||||||
b.xform.basis = basis;
|
b.xform.basis = basis;
|
||||||
Array args;
|
Array args;
|
||||||
args.push_back(
|
args.push_back(
|
||||||
lines[line].buildings[i].building_key);
|
::lines[line].buildings[i].building_key);
|
||||||
EditorEvent::get_singleton()->event.emit(
|
EditorEvent::get_singleton()->event.emit(
|
||||||
"building_updated", args);
|
"building_updated", args);
|
||||||
} else {
|
} else {
|
||||||
Vector3 pt = get_point_by_offsets(
|
Vector3 pt = get_point_by_offsets(
|
||||||
line,
|
line,
|
||||||
lines[line].buildings[i].line_offset,
|
::lines[line].buildings[i].line_offset,
|
||||||
lines[line].buildings[i].normal_offset);
|
::lines[line]
|
||||||
|
.buildings[i]
|
||||||
|
.normal_offset);
|
||||||
Basis basis = Basis().rotated(
|
Basis basis = Basis().rotated(
|
||||||
Vector3(0, 1, 0),
|
Vector3(0, 1, 0),
|
||||||
lines[line].buildings[i].y_rotation);
|
::lines[line].buildings[i].y_rotation);
|
||||||
struct BuildingsData::building nb;
|
struct BuildingsData::building nb;
|
||||||
Dictionary data;
|
Dictionary data;
|
||||||
data["id"] = lines[line].buildings[i].id;
|
data["id"] = ::lines[line].buildings[i].id;
|
||||||
data["xform"] = Transform(basis, pt);
|
data["xform"] = Transform(basis, pt);
|
||||||
BuildingsData::building::from_dict(&nb, data);
|
BuildingsData::building::from_dict(&nb, data);
|
||||||
String bkey = bd->create_building(nb);
|
String bkey = bd->create_building(nb);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public:
|
|||||||
const Dictionary &from);
|
const Dictionary &from);
|
||||||
Dictionary to_dict() const;
|
Dictionary to_dict() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
struct line_segment {
|
struct line_segment {
|
||||||
Vector3 p1;
|
Vector3 p1;
|
||||||
Vector3 p2;
|
Vector3 p2;
|
||||||
@@ -33,6 +35,8 @@ public:
|
|||||||
Vector3 tangent;
|
Vector3 tangent;
|
||||||
float offset;
|
float offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
struct road_line {
|
struct road_line {
|
||||||
std::vector<Transform> points;
|
std::vector<Transform> points;
|
||||||
std::vector<int> indices;
|
std::vector<int> indices;
|
||||||
@@ -44,14 +48,28 @@ public:
|
|||||||
Dictionary metadata;
|
Dictionary metadata;
|
||||||
_Signal<void> line_updated;
|
_Signal<void> line_updated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
static ImmediateGeometry *get_debug_node();
|
static ImmediateGeometry *get_debug_node();
|
||||||
HashMap<String, struct road_line> lines;
|
|
||||||
|
private:
|
||||||
HashMap<String, Ref<Curve3D> > curves;
|
HashMap<String, Ref<Curve3D> > curves;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const struct road_line &get_line(const String &key) const;
|
||||||
|
struct road_line &get_line(const String &key);
|
||||||
|
const struct road_line &lines(const String &key) const;
|
||||||
|
struct road_line &lines(const String &key);
|
||||||
|
bool has_line(const String &key);
|
||||||
|
|
||||||
static RoadLinesData *get_singleton();
|
static RoadLinesData *get_singleton();
|
||||||
virtual ~RoadLinesData();
|
virtual ~RoadLinesData();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
String get_road_lines_path();
|
String get_road_lines_path();
|
||||||
void get_road_lines_key_list(List<String> *keys);
|
void get_road_lines_key_list(List<String> *keys);
|
||||||
|
void get_lines_key_list(List<String> *keys);
|
||||||
|
const String &get_next_line(const String &key);
|
||||||
|
void erase_line(const String &key);
|
||||||
void load_data();
|
void load_data();
|
||||||
void save_data();
|
void save_data();
|
||||||
void process_lines(std::unordered_map<uint32_t, std::vector<Vector3> >
|
void process_lines(std::unordered_map<uint32_t, std::vector<Vector3> >
|
||||||
|
|||||||
@@ -314,11 +314,11 @@ protected:
|
|||||||
editor->get_as_node<ItemList>("%line_buildings_list");
|
editor->get_as_node<ItemList>("%line_buildings_list");
|
||||||
items->clear();
|
items->clear();
|
||||||
for (i = 0; i < (int)RoadLinesData::get_singleton()
|
for (i = 0; i < (int)RoadLinesData::get_singleton()
|
||||||
->lines[current_line]
|
->lines(current_line)
|
||||||
.buildings.size();
|
.buildings.size();
|
||||||
i++) {
|
i++) {
|
||||||
const String &key = RoadLinesData::get_singleton()
|
const String &key = RoadLinesData::get_singleton()
|
||||||
->lines[current_line]
|
->lines(current_line)
|
||||||
.buildings[i]
|
.buildings[i]
|
||||||
.building_key;
|
.building_key;
|
||||||
items->add_item(key);
|
items->add_item(key);
|
||||||
@@ -615,7 +615,7 @@ Node *RoadLinesEditor::scene()
|
|||||||
void RoadLinesEditor::update_line_geometry()
|
void RoadLinesEditor::update_line_geometry()
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
if (!rld->lines.has(current_line)) {
|
if (!rld->has_line(current_line)) {
|
||||||
if (line_im)
|
if (line_im)
|
||||||
line_im->clear();
|
line_im->clear();
|
||||||
return;
|
return;
|
||||||
@@ -629,16 +629,16 @@ void RoadLinesEditor::update_line_geometry()
|
|||||||
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
|
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
line_im->add_vertex(Vector3(0.0f, 100.0f, 0.0f));
|
line_im->add_vertex(Vector3(0.0f, 100.0f, 0.0f));
|
||||||
line_im->end();
|
line_im->end();
|
||||||
if (rld->lines[current_line].points.size() > 1) {
|
if (rld->lines(current_line).points.size() > 1) {
|
||||||
line_im->begin(Mesh::PRIMITIVE_LINES);
|
line_im->begin(Mesh::PRIMITIVE_LINES);
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
i <
|
i <
|
||||||
(int)rld->lines[current_line].points.size() - 1;
|
(int)rld->lines(current_line).points.size() - 1;
|
||||||
i++) {
|
i++) {
|
||||||
Vector3 pt1 = rld->lines[current_line]
|
Vector3 pt1 = rld->lines(current_line)
|
||||||
.points[i]
|
.points[i]
|
||||||
.origin;
|
.origin;
|
||||||
Vector3 pt2 = rld->lines[current_line]
|
Vector3 pt2 = rld->lines(current_line)
|
||||||
.points[i + 1]
|
.points[i + 1]
|
||||||
.origin;
|
.origin;
|
||||||
line_im->set_color(
|
line_im->set_color(
|
||||||
@@ -659,14 +659,14 @@ void RoadLinesEditor::update_line_geometry()
|
|||||||
}
|
}
|
||||||
// FIXME: update line segments on load and when line is changed
|
// FIXME: update line segments on load and when line is changed
|
||||||
rld->update_line_segments(current_line);
|
rld->update_line_segments(current_line);
|
||||||
if (rld->lines[current_line].buildings.size() > 1) {
|
if (rld->lines(current_line).buildings.size() > 1) {
|
||||||
line_im->begin(Mesh::PRIMITIVE_LINES);
|
line_im->begin(Mesh::PRIMITIVE_LINES);
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
i < (int)rld->lines[current_line].buildings.size();
|
i < (int)rld->lines(current_line).buildings.size();
|
||||||
i++) {
|
i++) {
|
||||||
print_line("idx: " + itos(i));
|
print_line("idx: " + itos(i));
|
||||||
const RoadLinesData::line_building_data &b =
|
const RoadLinesData::line_building_data &b =
|
||||||
rld->lines[current_line].buildings[i];
|
rld->lines(current_line).buildings[i];
|
||||||
Vector3 pt = rld->get_point_by_offsets(
|
Vector3 pt = rld->get_point_by_offsets(
|
||||||
current_line, b.line_offset,
|
current_line, b.line_offset,
|
||||||
b.normal_offset);
|
b.normal_offset);
|
||||||
@@ -686,14 +686,14 @@ void RoadLinesEditor::update_line_index_ui()
|
|||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
|
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
|
||||||
sp_line_index->set_max(rld->lines[current_line].points.size() - 1);
|
sp_line_index->set_max(rld->lines(current_line).points.size() - 1);
|
||||||
sp_line_index->set_min(0);
|
sp_line_index->set_min(0);
|
||||||
}
|
}
|
||||||
void RoadLinesEditor::select_line(const String &line_name)
|
void RoadLinesEditor::select_line(const String &line_name)
|
||||||
{
|
{
|
||||||
print_line("selected line: " + line_name);
|
print_line("selected line: " + line_name);
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
assert(rld->lines.has(line_name));
|
assert(rld->has_line(line_name));
|
||||||
if (current_line != line_name) {
|
if (current_line != line_name) {
|
||||||
current_line = line_name;
|
current_line = line_name;
|
||||||
update_line_index_ui();
|
update_line_index_ui();
|
||||||
@@ -713,7 +713,7 @@ void RoadLinesEditor::select_line(const String &line_name)
|
|||||||
bool RoadLinesEditor::line_exists(const String &line_name)
|
bool RoadLinesEditor::line_exists(const String &line_name)
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
return rld->lines.has(line_name);
|
return rld->has_line(line_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoadLinesEditor::line_create_point()
|
void RoadLinesEditor::line_create_point()
|
||||||
@@ -724,8 +724,10 @@ void RoadLinesEditor::line_create_point()
|
|||||||
Vector3 position = get_cursor_position();
|
Vector3 position = get_cursor_position();
|
||||||
Transform xform(Basis(), position);
|
Transform xform(Basis(), position);
|
||||||
int index = get_line_index();
|
int index = get_line_index();
|
||||||
rld->lines[current_line].points.insert(
|
rld->lines(current_line)
|
||||||
rld->lines[current_line].points.begin() + index + 1, xform);
|
.points.insert(rld->lines(current_line).points.begin() + index +
|
||||||
|
1,
|
||||||
|
xform);
|
||||||
Array args;
|
Array args;
|
||||||
args.push_back(current_line);
|
args.push_back(current_line);
|
||||||
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
||||||
@@ -742,10 +744,10 @@ void RoadLinesEditor::line_delete_point()
|
|||||||
print_line("line_delete_point");
|
print_line("line_delete_point");
|
||||||
int index = get_line_index();
|
int index = get_line_index();
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
if (rld->lines[current_line].points.size() < 2)
|
if (rld->lines(current_line).points.size() < 2)
|
||||||
return;
|
return;
|
||||||
rld->lines[current_line].points.erase(
|
rld->lines(current_line)
|
||||||
rld->lines[current_line].points.begin() + index);
|
.points.erase(rld->lines(current_line).points.begin() + index);
|
||||||
Array args;
|
Array args;
|
||||||
args.push_back(current_line);
|
args.push_back(current_line);
|
||||||
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
||||||
@@ -766,12 +768,12 @@ void RoadLinesEditor::set_point_to_cursor()
|
|||||||
Spatial *cursor = get_as_node<Spatial>(cursor_name);
|
Spatial *cursor = get_as_node<Spatial>(cursor_name);
|
||||||
Transform xform = cursor->get_global_transform();
|
Transform xform = cursor->get_global_transform();
|
||||||
int index = get_line_index();
|
int index = get_line_index();
|
||||||
rld->lines[current_line].points[index].origin = xform.origin;
|
rld->lines(current_line).points[index].origin = xform.origin;
|
||||||
Array args;
|
Array args;
|
||||||
args.push_back(current_line);
|
args.push_back(current_line);
|
||||||
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
||||||
update_line_geometry();
|
update_line_geometry();
|
||||||
set_ui_point_position(rld->lines[current_line].points[index].origin);
|
set_ui_point_position(rld->lines(current_line).points[index].origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RoadLinesEditor::get_line_index()
|
int RoadLinesEditor::get_line_index()
|
||||||
@@ -787,7 +789,7 @@ void RoadLinesEditor::move_cursor_to_point()
|
|||||||
print_line("move_cursor_to_point");
|
print_line("move_cursor_to_point");
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
int index = get_line_index();
|
int index = get_line_index();
|
||||||
Transform xform(Basis(), rld->lines[current_line].points[index].origin);
|
Transform xform(Basis(), rld->lines(current_line).points[index].origin);
|
||||||
set_cursor_position(xform.origin);
|
set_cursor_position(xform.origin);
|
||||||
set_ui_cursor_position(xform.origin);
|
set_ui_cursor_position(xform.origin);
|
||||||
}
|
}
|
||||||
@@ -899,7 +901,7 @@ void RoadLinesEditor::update_ui()
|
|||||||
get_as_node<Control>("%road_lines_buildings")->hide();
|
get_as_node<Control>("%road_lines_buildings")->hide();
|
||||||
ItemList *lines_list = get_as_node<ItemList>("%lines_list");
|
ItemList *lines_list = get_as_node<ItemList>("%lines_list");
|
||||||
List<String> line_keys;
|
List<String> line_keys;
|
||||||
rld->lines.get_key_list(&line_keys);
|
rld->get_lines_key_list(&line_keys);
|
||||||
List<String>::Element *e = line_keys.front();
|
List<String>::Element *e = line_keys.front();
|
||||||
lines_list->clear();
|
lines_list->clear();
|
||||||
if (!re.is_valid())
|
if (!re.is_valid())
|
||||||
@@ -942,7 +944,7 @@ void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
|
|||||||
rline.pattern = 0;
|
rline.pattern = 0;
|
||||||
Transform cursor_position(Basis(), get_cursor_position());
|
Transform cursor_position(Basis(), get_cursor_position());
|
||||||
rline.points.push_back(cursor_position);
|
rline.points.push_back(cursor_position);
|
||||||
rld->lines[line_name] = rline;
|
rld->lines(line_name) = rline;
|
||||||
update_line_index_ui();
|
update_line_index_ui();
|
||||||
update_ui();
|
update_ui();
|
||||||
}
|
}
|
||||||
@@ -951,9 +953,8 @@ void RoadLinesEditor::delete_current_line()
|
|||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
String delete_line = current_line;
|
String delete_line = current_line;
|
||||||
const String *k = rld->lines.next(&delete_line);
|
current_line = rld->get_next_line(delete_line);
|
||||||
current_line = *k;
|
rld->erase_line(delete_line);
|
||||||
rld->lines.erase(delete_line);
|
|
||||||
update_line_index_ui();
|
update_line_index_ui();
|
||||||
update_ui();
|
update_ui();
|
||||||
}
|
}
|
||||||
@@ -976,7 +977,7 @@ void RoadLinesEditor::set_point_position(const Vector3 &position)
|
|||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
int index = get_line_index();
|
int index = get_line_index();
|
||||||
rld->lines[current_line].points[index].origin = position;
|
rld->lines(current_line).points[index].origin = position;
|
||||||
Array args;
|
Array args;
|
||||||
args.push_back(current_line);
|
args.push_back(current_line);
|
||||||
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
|
||||||
@@ -1004,9 +1005,9 @@ void RoadLinesEditor::set_ui_point_position(const Vector3 &point_position)
|
|||||||
void RoadLinesEditor::set_line_index(int index)
|
void RoadLinesEditor::set_line_index(int index)
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
assert(rld->lines.has(current_line));
|
assert(rld->has_line(current_line));
|
||||||
assert(index < (int)rld->lines[current_line].points.size());
|
assert(index < (int)rld->lines(current_line).points.size());
|
||||||
Vector3 point_position = rld->lines[current_line].points[index].origin;
|
Vector3 point_position = rld->lines(current_line).points[index].origin;
|
||||||
Vector3 cursor_position = point_position;
|
Vector3 cursor_position = point_position;
|
||||||
set_cursor_position(cursor_position);
|
set_cursor_position(cursor_position);
|
||||||
set_ui_cursor_position(cursor_position);
|
set_ui_cursor_position(cursor_position);
|
||||||
@@ -1227,7 +1228,7 @@ void RoadLinesEditor::save_data()
|
|||||||
void RoadLinesEditor::update_current_line_metadata(const String &text)
|
void RoadLinesEditor::update_current_line_metadata(const String &text)
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
assert(rld->lines.has(current_line));
|
assert(rld->has_line(current_line));
|
||||||
if (!text.begins_with("{"))
|
if (!text.begins_with("{"))
|
||||||
return;
|
return;
|
||||||
String err_s;
|
String err_s;
|
||||||
@@ -1243,13 +1244,13 @@ void RoadLinesEditor::update_current_line_metadata(const String &text)
|
|||||||
print_line("Invalid metadata type, should be Dictionary");
|
print_line("Invalid metadata type, should be Dictionary");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rld->lines[current_line].metadata = v;
|
rld->lines(current_line).metadata = v;
|
||||||
}
|
}
|
||||||
String RoadLinesEditor::get_current_line_metadata() const
|
String RoadLinesEditor::get_current_line_metadata() const
|
||||||
{
|
{
|
||||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||||
assert(rld->lines.has(current_line));
|
assert(rld->has_line(current_line));
|
||||||
return JSON::print(rld->lines[current_line].metadata, "\t", true);
|
return JSON::print(rld->lines(current_line).metadata, "\t", true);
|
||||||
}
|
}
|
||||||
void RoadLinesEditor::remove_generated_stuff()
|
void RoadLinesEditor::remove_generated_stuff()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,14 +63,14 @@ struct RoadLinesProcessing {
|
|||||||
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();
|
||||||
if (rld->lines[key].indices.size() < 2) {
|
if (rld->lines(key).indices.size() < 2) {
|
||||||
e = e->next();
|
e = e->next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (int)rld->lines[key].indices.size() - 1;
|
for (i = 0; i < (int)rld->lines(key).indices.size() - 1;
|
||||||
i++) {
|
i++) {
|
||||||
int idx1 = rld->lines[key].indices[i];
|
int idx1 = rld->lines(key).indices[i];
|
||||||
int idx2 = rld->lines[key].indices[i + 1];
|
int idx2 = rld->lines(key).indices[i + 1];
|
||||||
if (edges.find(idx1) == edges.end()) {
|
if (edges.find(idx1) == edges.end()) {
|
||||||
struct edgedata ed;
|
struct edgedata ed;
|
||||||
ed.neighbors.clear();
|
ed.neighbors.clear();
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ void StreamWorld::create_tilemap()
|
|||||||
{
|
{
|
||||||
data()->for_each_building(
|
data()->for_each_building(
|
||||||
[this](const String &key, void *hdata) {
|
[this](const String &key, void *hdata) {
|
||||||
int tile_x = data()->get_building(key).xform.origin.x /
|
const struct BuildingsData::building &b =
|
||||||
tile_size;
|
data()->get_building(key);
|
||||||
int tile_z = data()->get_building(key).xform.origin.z /
|
int tile_x = b.xform.origin.x / tile_size;
|
||||||
tile_size;
|
int tile_z = b.xform.origin.z / tile_size;
|
||||||
std::tuple<int, int> tkey =
|
std::tuple<int, int> tkey =
|
||||||
std::make_tuple(tile_x, tile_z);
|
std::make_tuple(tile_x, tile_z);
|
||||||
if (tiles.find(tkey) != tiles.end())
|
if (tiles.find(tkey) != tiles.end())
|
||||||
@@ -32,19 +32,6 @@ void StreamWorld::create_tilemap()
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
nullptr);
|
nullptr);
|
||||||
#if 0
|
|
||||||
for (i = 0; i < (int)data()->get_building_count(); i++) {
|
|
||||||
int tile_x = data()->get_building(i).xform.origin.x / tile_size;
|
|
||||||
int tile_z = data()->get_building(i).xform.origin.z / tile_size;
|
|
||||||
std::tuple<int, int> key = std::make_tuple(tile_x, tile_z);
|
|
||||||
if (tiles.find(key) != tiles.end())
|
|
||||||
tiles[key].push_back(i);
|
|
||||||
else {
|
|
||||||
std::vector<int> data = { i };
|
|
||||||
tiles[key] = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
print_line("Tile count: " + itos(tiles.size()));
|
print_line("Tile count: " + itos(tiles.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +230,7 @@ void StreamWorld::remove_building(const String &key)
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
unload_building(key);
|
unload_building(key);
|
||||||
data()->destroy_building(key);
|
data()->destroy_building(key);
|
||||||
data()->item_nodes_item_removed(key);
|
assert(!data()->has_building(key));
|
||||||
update_items();
|
update_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +339,7 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
for (i = erased_keys.size() - 1; i >= 0; i--) {
|
for (i = erased_keys.size() - 1; i >= 0; i--) {
|
||||||
unload_building(erased_keys[i]);
|
unload_building(erased_keys[i]);
|
||||||
data()->destroy_building(erased_keys[i]);
|
data()->destroy_building(erased_keys[i]);
|
||||||
data()->item_nodes_item_removed(erased_keys[i]);
|
assert(!data()->has_building(erased_keys[i]));
|
||||||
}
|
}
|
||||||
update_items();
|
update_items();
|
||||||
} else if (command == "remove_generated_stuff") {
|
} else if (command == "remove_generated_stuff") {
|
||||||
@@ -475,7 +462,7 @@ void StreamWorld::remove_generated_stuff()
|
|||||||
const String &key = erased_keys[i];
|
const String &key = erased_keys[i];
|
||||||
unload_building(key);
|
unload_building(key);
|
||||||
data()->destroy_building(key);
|
data()->destroy_building(key);
|
||||||
data()->item_nodes_item_removed(key);
|
assert(!data()->has_building(key));
|
||||||
}
|
}
|
||||||
update_items();
|
update_items();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user