Update - fixed lots generation, now can save lots polygons

This commit is contained in:
2025-02-26 08:02:41 +03:00
parent 66838892d5
commit d79222c86c
36 changed files with 4055 additions and 2823 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -16,7 +16,9 @@
1, 1,
2, 2,
3, 3,
4 4,
5,
6
] ]
} }
], ],
@@ -47,27 +49,34 @@
"mesh":3, "mesh":3,
"name":"roadd-sidewalk_end", "name":"roadd-sidewalk_end",
"translation":[ "translation":[
3.3000001907348633, 4.8000006675720215,
0, 0,
0 0
] ]
}, },
{ {
"mesh":4, "mesh":4,
"name":"roadd-sidewalk_start", "name":"road-lane-sidwalk-sideroad",
"rotation":[
0,
0,
-1,
0
],
"scale":[
-1,
-1,
-1
],
"translation":[ "translation":[
4.55145263671875, 6.099999904632568,
0,
0
]
},
{
"mesh":5,
"name":"roadd-sidewalk_start",
"translation":[
3.500000238418579,
0,
0
]
},
{
"mesh":6,
"name":"road-lane-lot",
"translation":[
8,
0, 0,
0 0
] ]
@@ -78,9 +87,9 @@
"extensions":{ "extensions":{
"KHR_materials_specular":{ "KHR_materials_specular":{
"specularColorFactor":[ "specularColorFactor":[
0.474271529955476, 0.118567882488869,
0.474271529955476, 0.118567882488869,
0.474271529955476 0.118567882488869
] ]
}, },
"KHR_materials_ior":{ "KHR_materials_ior":{
@@ -92,7 +101,10 @@
"baseColorTexture":{ "baseColorTexture":{
"index":0 "index":0
}, },
"metallicFactor":0.20000000298023224 "metallicFactor":0.05000000074505806,
"metallicRoughnessTexture":{
"index":1
}
} }
} }
], ],
@@ -140,7 +152,7 @@
] ]
}, },
{ {
"name":"road-sidewalk.001", "name":"road-sidewalk-end",
"primitives":[ "primitives":[
{ {
"attributes":{ "attributes":{
@@ -154,7 +166,7 @@
] ]
}, },
{ {
"name":"road-sidewalk.006", "name":"road-sidewalk-sideroad",
"primitives":[ "primitives":[
{ {
"attributes":{ "attributes":{
@@ -162,7 +174,36 @@
"NORMAL":17, "NORMAL":17,
"TEXCOORD_0":18 "TEXCOORD_0":18
}, },
"indices":15, "indices":19,
"material":0
}
]
},
{
"name":"road-sidewalk-start",
"primitives":[
{
"attributes":{
"POSITION":20,
"NORMAL":21,
"TEXCOORD_0":22
},
"indices":23,
"material":0
}
]
},
{
"name":"road-lot",
"primitives":[
{
"attributes":{
"COLOR_0":24,
"POSITION":25,
"NORMAL":26,
"TEXCOORD_0":27
},
"indices":28,
"material":0 "material":0
} }
] ]
@@ -172,6 +213,10 @@
{ {
"sampler":0, "sampler":0,
"source":0 "source":0
},
{
"sampler":0,
"source":1
} }
], ],
"images":[ "images":[
@@ -179,6 +224,11 @@
"mimeType":"image/png", "mimeType":"image/png",
"name":"road", "name":"road",
"uri":"road.png" "uri":"road.png"
},
{
"mimeType":"image/png",
"name":"roughness",
"uri":"roughness.png"
} }
], ],
"accessors":[ "accessors":[
@@ -187,12 +237,12 @@
"componentType":5126, "componentType":5126,
"count":32, "count":32,
"max":[ "max":[
-8.847564458847046e-09, 0,
0.12099996209144592, 0.12867334485054016,
5.960464477539063e-08 5.960464477539063e-08
], ],
"min":[ "min":[
-0.9999999403953552, -1,
-0.09999995678663254, -0.09999995678663254,
-0.5 -0.5
], ],
@@ -219,11 +269,11 @@
{ {
"bufferView":4, "bufferView":4,
"componentType":5126, "componentType":5126,
"count":74, "count":76,
"max":[ "max":[
9.921204764395952e-07, 1.0132789611816406e-06,
0.1214386522769928, 0.12219604849815369,
-6.735790520906448e-07 -6.705522537231445e-07
], ],
"min":[ "min":[
-0.9999990463256836, -0.9999990463256836,
@@ -235,13 +285,13 @@
{ {
"bufferView":5, "bufferView":5,
"componentType":5126, "componentType":5126,
"count":74, "count":76,
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":6, "bufferView":6,
"componentType":5126, "componentType":5126,
"count":74, "count":76,
"type":"VEC2" "type":"VEC2"
}, },
{ {
@@ -253,9 +303,9 @@
{ {
"bufferView":8, "bufferView":8,
"componentType":5126, "componentType":5126,
"count":40, "count":42,
"max":[ "max":[
2.5033950805664062e-05, 0.0032810475677251816,
0.19999995827674866, 0.19999995827674866,
0 0
], ],
@@ -269,13 +319,13 @@
{ {
"bufferView":9, "bufferView":9,
"componentType":5126, "componentType":5126,
"count":40, "count":42,
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":10, "bufferView":10,
"componentType":5126, "componentType":5126,
"count":40, "count":42,
"type":"VEC2" "type":"VEC2"
}, },
{ {
@@ -287,64 +337,145 @@
{ {
"bufferView":12, "bufferView":12,
"componentType":5126, "componentType":5126,
"count":418, "count":433,
"max":[ "max":[
0.00867057777941227, 0.008670568466186523,
0.19999998807907104, 0.19999998807907104,
0 2.6469779601696886e-23
], ],
"min":[ "min":[
-1.100000023841858, -1.1999990940093994,
-0.10000000149011612, -0.10000000894069672,
-0.5000007152557373 -0.5
], ],
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":13, "bufferView":13,
"componentType":5126, "componentType":5126,
"count":418, "count":433,
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":14, "bufferView":14,
"componentType":5126, "componentType":5126,
"count":418, "count":433,
"type":"VEC2" "type":"VEC2"
}, },
{ {
"bufferView":15, "bufferView":15,
"componentType":5123, "componentType":5123,
"count":975, "count":972,
"type":"SCALAR" "type":"SCALAR"
}, },
{ {
"bufferView":16, "bufferView":16,
"componentType":5126, "componentType":5126,
"count":418, "count":29,
"max":[ "max":[
0.00867057777941227, 0.008670799434185028,
0.19999998807907104, 0.12041480839252472,
0.5 5.960464477539063e-08
], ],
"min":[ "min":[
-1.100000023841858, -1.1999988555908203,
-0.10000000149011612, -0.09999999403953552,
-7.152557373046875e-07 -0.5
], ],
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":17, "bufferView":17,
"componentType":5126, "componentType":5126,
"count":418, "count":29,
"type":"VEC3" "type":"VEC3"
}, },
{ {
"bufferView":18, "bufferView":18,
"componentType":5126, "componentType":5126,
"count":418, "count":29,
"type":"VEC2" "type":"VEC2"
},
{
"bufferView":19,
"componentType":5123,
"count":60,
"type":"SCALAR"
},
{
"bufferView":20,
"componentType":5126,
"count":429,
"max":[
0.008670568466186523,
0.19999998807907104,
0
],
"min":[
-1.1999990940093994,
-0.10000000894069672,
-0.5
],
"type":"VEC3"
},
{
"bufferView":21,
"componentType":5126,
"count":429,
"type":"VEC3"
},
{
"bufferView":22,
"componentType":5126,
"count":429,
"type":"VEC2"
},
{
"bufferView":23,
"componentType":5123,
"count":972,
"type":"SCALAR"
},
{
"bufferView":24,
"componentType":5123,
"count":259,
"normalized":true,
"type":"VEC4"
},
{
"bufferView":25,
"componentType":5126,
"count":259,
"max":[
4.4345855712890625e-05,
0.11039861291646957,
3.874301910400391e-06
],
"min":[
-1.000115156173706,
-0.036179300397634506,
-0.45530906319618225
],
"type":"VEC3"
},
{
"bufferView":26,
"componentType":5126,
"count":259,
"type":"VEC3"
},
{
"bufferView":27,
"componentType":5126,
"count":259,
"type":"VEC2"
},
{
"bufferView":28,
"componentType":5123,
"count":1101,
"type":"SCALAR"
} }
], ],
"bufferViews":[ "bufferViews":[
@@ -374,93 +505,153 @@
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":888, "byteLength":912,
"byteOffset":1120, "byteOffset":1120,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":888, "byteLength":912,
"byteOffset":2008, "byteOffset":2032,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":592, "byteLength":608,
"byteOffset":2896, "byteOffset":2944,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":252, "byteLength":252,
"byteOffset":3488, "byteOffset":3552,
"target":34963 "target":34963
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":480, "byteLength":504,
"byteOffset":3740, "byteOffset":3804,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":480, "byteLength":504,
"byteOffset":4220, "byteOffset":4308,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":320, "byteLength":336,
"byteOffset":4700, "byteOffset":4812,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":132, "byteLength":132,
"byteOffset":5020, "byteOffset":5148,
"target":34963 "target":34963
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":5016, "byteLength":5196,
"byteOffset":5152, "byteOffset":5280,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":5016, "byteLength":5196,
"byteOffset":10168, "byteOffset":10476,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":3344, "byteLength":3464,
"byteOffset":15184, "byteOffset":15672,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":1950, "byteLength":1944,
"byteOffset":18528, "byteOffset":19136,
"target":34963 "target":34963
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":5016, "byteLength":348,
"byteOffset":20480, "byteOffset":21080,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":5016, "byteLength":348,
"byteOffset":25496, "byteOffset":21428,
"target":34962 "target":34962
}, },
{ {
"buffer":0, "buffer":0,
"byteLength":3344, "byteLength":232,
"byteOffset":30512, "byteOffset":21776,
"target":34962 "target":34962
},
{
"buffer":0,
"byteLength":120,
"byteOffset":22008,
"target":34963
},
{
"buffer":0,
"byteLength":5148,
"byteOffset":22128,
"target":34962
},
{
"buffer":0,
"byteLength":5148,
"byteOffset":27276,
"target":34962
},
{
"buffer":0,
"byteLength":3432,
"byteOffset":32424,
"target":34962
},
{
"buffer":0,
"byteLength":1944,
"byteOffset":35856,
"target":34963
},
{
"buffer":0,
"byteLength":2072,
"byteOffset":37800,
"target":34962
},
{
"buffer":0,
"byteLength":3108,
"byteOffset":39872,
"target":34962
},
{
"buffer":0,
"byteLength":3108,
"byteOffset":42980,
"target":34962
},
{
"buffer":0,
"byteLength":2072,
"byteOffset":46088,
"target":34962
},
{
"buffer":0,
"byteLength":2202,
"byteOffset":48160,
"target":34963
} }
], ],
"samplers":[ "samplers":[
@@ -471,7 +662,7 @@
], ],
"buffers":[ "buffers":[
{ {
"byteLength":33856, "byteLength":50364,
"uri":"road-lanes.bin" "uri":"road-lanes.bin"
} }
] ]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -2,28 +2,30 @@
importer="texture" importer="texture"
type="StreamTexture" type="StreamTexture"
path="res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.stex" path.s3tc="res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.s3tc.stex"
path.etc2="res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.etc2.stex"
metadata={ metadata={
"vram_texture": false "imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
} }
[deps] [deps]
source_file="res://astream/road/road.png" source_file="res://astream/road/road.png"
dest_files=[ "res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.stex" ] dest_files=[ "res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.s3tc.stex", "res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.etc2.stex" ]
[params] [params]
compress/mode=0 compress/mode=2
compress/lossy_quality=0.7 compress/lossy_quality=0.7
compress/hdr_mode=0 compress/hdr_mode=0
compress/bptc_ldr=0 compress/bptc_ldr=0
compress/normal_map=0 compress/normal_map=0
flags/repeat=0 flags/repeat=true
flags/filter=true flags/filter=true
flags/mipmaps=false flags/mipmaps=true
flags/anisotropic=false flags/anisotropic=false
flags/srgb=2 flags/srgb=1
process/fix_alpha_border=true process/fix_alpha_border=true
process/premult_alpha=false process/premult_alpha=false
process/HDR_as_SRGB=false process/HDR_as_SRGB=false
@@ -31,5 +33,5 @@ process/invert_color=false
process/normal_map_invert_y=false process/normal_map_invert_y=false
stream=false stream=false
size_limit=0 size_limit=0
detect_3d=true detect_3d=false
svg/scale=1.0 svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/roughness.png-d2a962b97bf129a7543624215e5981e2.s3tc.stex"
path.etc2="res://.import/roughness.png-d2a962b97bf129a7543624215e5981e2.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://astream/road/roughness.png"
dest_files=[ "res://.import/roughness.png-d2a962b97bf129a7543624215e5981e2.s3tc.stex", "res://.import/roughness.png-d2a962b97bf129a7543624215e5981e2.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

File diff suppressed because it is too large Load Diff

View File

@@ -57,6 +57,10 @@ road_lines_path = "res://astream/road_lines.json"
center_mesh = "res://astream/road/road-lanes_road-lane-center.mesh" center_mesh = "res://astream/road/road-lanes_road-lane-center.mesh"
mid_mesh = "res://astream/road/road-lanes_road-lane-mid.mesh" mid_mesh = "res://astream/road/road-lanes_road-lane-mid.mesh"
sidewalk_mesh = "res://astream/road/road-lanes_road-sidewalk.mesh" sidewalk_mesh = "res://astream/road/road-lanes_road-sidewalk.mesh"
sidewalk_start_mesh = "res://astream/road/road-lanes_road-sidewalk-start.mesh"
sidewalk_end_mesh = "res://astream/road/road-lanes_road-sidewalk-end.mesh"
sidewalk_sideroad_mesh = "res://astream/road/road-lanes_road-sidewalk-sideroad.mesh"
lot_mesh = "res://astream/road/road-lanes_road-lot.mesh"
[lines] [lines]
road_lines_path = "res://astream/road_lines.json" road_lines_path = "res://astream/road_lines.json"
gen_prefixes = ["empty", "foundation30", "foundation60", "sideroad-start", gen_prefixes = ["empty", "foundation30", "foundation60", "sideroad-start",

View File

@@ -10,7 +10,6 @@ env_stream.module_obj = []
env_stream.Prepend(CPPPATH=["../../meshoptimizer/src"]) env_stream.Prepend(CPPPATH=["../../meshoptimizer/src"])
env_stream.Prepend(CPPPATH=["event"]) env_stream.Prepend(CPPPATH=["event"])
env_stream.add_source_files(env_stream.module_obj, "*.cpp") env_stream.add_source_files(env_stream.module_obj, "*.cpp")
env_stream.add_source_files(env_stream.module_obj, "flecs/*.c")
env.modules_sources += env_stream.module_obj env.modules_sources += env_stream.module_obj
SConscript("buildings/SCsub") SConscript("buildings/SCsub")
@@ -18,6 +17,7 @@ SConscript("rtree/SCsub")
SConscript("ui/SCsub") SConscript("ui/SCsub")
SConscript("npc/SCsub") SConscript("npc/SCsub")
SConscript("event/SCsub") SConscript("event/SCsub")
SConscript("flecs/SCsub")

View File

@@ -181,7 +181,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
while (e) { while (e) {
struct building b; struct building b;
String key = e->get(); String key = e->get();
if (!key.begins_with("road::")) { if (!key.begins_with("road::") && !key.begins_with("road__")) {
Dictionary entry = json[key]; Dictionary entry = json[key];
String id = entry.get("id", "empty"); String id = entry.get("id", "empty");
if (id == "empty") { if (id == "empty") {
@@ -216,7 +216,7 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
ecs().each([&index, &json](const CBuildingData &b) { ecs().each([&index, &json](const CBuildingData &b) {
String key = b.building.key; String key = b.building.key;
/* do not save roadside generated stuff */ /* do not save roadside generated stuff */
if (!key.begins_with("road::")) { if (!key.begins_with("road::") && !key.begins_with("road__")) {
Dictionary dict = b.building.to_dict(); Dictionary dict = b.building.to_dict();
dict["index"] = index; dict["index"] = index;
json[key] = dict; json[key] = dict;
@@ -712,7 +712,6 @@ const struct BuildingsData::building &
BuildingsData::get_building(const String &building_key) const BuildingsData::get_building(const String &building_key) const
{ {
String ename = "base:" + building_key; String ename = "base:" + building_key;
print_line("get_building: " + ename);
flecs::entity e = lookup(ename); flecs::entity e = lookup(ename);
assert(e.is_valid()); assert(e.is_valid());
return e.get<CBuildingData>()->building; return e.get<CBuildingData>()->building;
@@ -722,7 +721,6 @@ 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;
print_line("get_building: " + ename);
flecs::entity e = lookup(ename); flecs::entity e = lookup(ename);
assert(e.is_valid()); assert(e.is_valid());
return e.get_mut<CBuildingData>()->building; return e.get_mut<CBuildingData>()->building;

View File

@@ -0,0 +1,12 @@
Import("env")
Import("env_modules")
env_stream = env_modules.Clone()
env_stream.stream_building_sources = []
env_stream.add_source_files(env_stream.stream_building_sources, "*.cpp")
lib = env_stream.add_library("event", env_stream.stream_building_sources)
env.Append(LIBS=[lib])
env_stream.Prepend(CPPPATH=[".."])
env_stream.Prepend(CPPPATH=["../../../meshoptimizer/src"])

View File

@@ -0,0 +1,32 @@
#undef NDEBUG
#include <cassert>
#include "editor_event.h"
EditorEvent *EditorEvent::singleton = nullptr;
EditorEvent::EditorEvent()
{
}
EditorEvent::~EditorEvent()
{
}
EditorEvent *EditorEvent::get_singleton()
{
if (!singleton)
singleton = memnew(EditorEvent);
return singleton;
}
void EditorEvent::EventHelper::emit(const String &event,
const Vector<Variant> &args)
{
auto evl = listeners.begin();
while (evl != listeners.end()) {
const event_listener_ptrs &xev = *evl;
xev.execute(event, args);
evl++;
}
}

View File

@@ -0,0 +1,81 @@
#ifndef EDITOR_EVENT_H
#define EDITOR_EVENT_H
#include <core/ustring.h>
#include <list>
class EditorEvent {
public:
class EventHelper {
class event_listener_ptrs {
public:
class H {};
H *obj;
void (H::*method)(const String &event,
const Vector<Variant> &args);
void execute(const String &event,
const Vector<Variant> &args) const
{
(obj->*method)(event, args);
}
};
std::list<event_listener_ptrs> listeners;
typedef event_listener_ptrs::H *obj_t;
typedef void (event_listener_ptrs::H::*method_t)(
const String &event, const Vector<Variant> &args);
public:
template <class T>
void
add_listener(T *obj,
void (T::*method)(const String &event,
const Vector<Variant> &args));
template <class T>
void
remove_listener(T *obj,
void (T::*method)(const String &event,
const Vector<Variant> &args));
void emit(const String &event, const Vector<Variant> &args);
};
EventHelper event;
private:
static EditorEvent *singleton;
EditorEvent();
virtual ~EditorEvent();
public:
static EditorEvent *get_singleton();
};
template <class T>
void EditorEvent::EventHelper::remove_listener(
T *obj,
void (T::*method)(const String &event, const Vector<Variant> &args))
{
listeners.remove_if([obj, method](const event_listener_ptrs &e) {
return e.obj == reinterpret_cast<obj_t>(obj) &&
e.method == reinterpret_cast<method_t>(method);
});
}
template <class T>
void EditorEvent::EventHelper::add_listener(
T *obj,
void (T::*method)(const String &event, const Vector<Variant> &args))
{
auto evl = listeners.begin();
bool bad = false;
while (evl != listeners.end()) {
const event_listener_ptrs &xev = *evl;
if (xev.obj == reinterpret_cast<obj_t>(obj) &&
xev.method == reinterpret_cast<method_t>(method)) {
bad = true;
break;
}
evl++;
}
if (bad)
return;
event_listener_ptrs ev;
ev.obj = reinterpret_cast<obj_t>(obj);
ev.method = reinterpret_cast<method_t>(method);
listeners.push_back(ev);
}
#endif

View File

@@ -0,0 +1,31 @@
#undef NDEBUG
#include <cassert>
#include "game_event.h"
GameEvent *GameEvent::singleton = nullptr;
GameEvent::GameEvent()
{
}
GameEvent::~GameEvent()
{
}
GameEvent *GameEvent::get_singleton()
{
if (!singleton)
singleton = memnew(GameEvent);
return singleton;
}
void GameEvent::EventHelper::emit(const String &event,
const Vector<Variant> &args)
{
auto evl = listeners.begin();
while (evl != listeners.end()) {
const event_listener_ptrs &xev = *evl;
xev.execute(event, args);
evl++;
}
}

View File

@@ -0,0 +1,83 @@
/* ~/godot-projects/streaming_world/src/modules/stream/game_event.h */
#ifndef GAME_EVENT_H_
#define GAME_EVENT_H_
#include <core/ustring.h>
#include <list>
class GameEvent {
public:
class EventHelper {
class event_listener_ptrs {
public:
class H {};
H *obj;
void (H::*method)(const String &event,
const Vector<Variant> &args);
void execute(const String &event,
const Vector<Variant> &args) const
{
(obj->*method)(event, args);
}
};
std::list<event_listener_ptrs> listeners;
typedef event_listener_ptrs::H *obj_t;
typedef void (event_listener_ptrs::H::*method_t)(
const String &event, const Vector<Variant> &args);
public:
template <class T>
void
add_listener(T *obj,
void (T::*method)(const String &event,
const Vector<Variant> &args));
template <class T>
void
remove_listener(T *obj,
void (T::*method)(const String &event,
const Vector<Variant> &args));
void emit(const String &event, const Vector<Variant> &args);
};
EventHelper event;
private:
static GameEvent *singleton;
GameEvent();
virtual ~GameEvent();
public:
static GameEvent *get_singleton();
};
template <class T>
void GameEvent::EventHelper::remove_listener(
T *obj,
void (T::*method)(const String &event, const Vector<Variant> &args))
{
listeners.remove_if([obj, method](const event_listener_ptrs &e) {
return e.obj == reinterpret_cast<obj_t>(obj) &&
e.method == reinterpret_cast<method_t>(method);
});
}
template <class T>
void GameEvent::EventHelper::add_listener(
T *obj,
void (T::*method)(const String &event, const Vector<Variant> &args))
{
auto evl = listeners.begin();
bool bad = false;
while (evl != listeners.end()) {
const event_listener_ptrs &xev = *evl;
if (xev.obj == reinterpret_cast<obj_t>(obj) &&
xev.method == reinterpret_cast<method_t>(method)) {
bad = true;
break;
}
evl++;
}
if (bad)
return;
event_listener_ptrs ev;
ev.obj = reinterpret_cast<obj_t>(obj);
ev.method = reinterpret_cast<method_t>(method);
listeners.push_back(ev);
}
#endif // GAME_EVENT_H_

View File

@@ -78,12 +78,86 @@ public:
const struct CLine *cl = e.get<CLine>(); const struct CLine *cl = e.get<CLine>();
return &cl->line; return &cl->line;
} }
inline struct RoadLinesData::road_line &get_line(const String &key) inline const struct RoadLinesData::road_edge &
get_line_edge(const String &key, int edge) const
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.edges[edge];
}
void set_line_edge(const String &key, int edge_id,
const struct RoadLinesData::road_edge &edge)
{ {
flecs::entity e = lookup(key); flecs::entity e = lookup(key);
struct CLine *cl = e.get_mut<CLine>(); struct CLine *cl = e.get_mut<CLine>();
cl->line.edges[edge_id] = edge;
e.modified<CLine>();
}
inline int get_line_edge_count(const String &key) const
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.edges.size();
}
void
set_line_edge_left(const String &key, int edge_id,
const struct RoadLinesData::road_edge_side &side)
{
// print_line("set_line_edge_left: " + key + " " + itos(edge_id) +
// " lot: " + itos(side.lot));
flecs::entity e = lookup(key);
struct CLine *cl = e.get_mut<CLine>();
cl->line.edges[edge_id].left = side;
e.modified<CLine>();
cl = e.get_mut<CLine>();
assert(cl->line.edges[edge_id].left.lot == side.lot);
}
void
set_line_edge_right(const String &key, int edge_id,
const struct RoadLinesData::road_edge_side &side)
{
// print_line("set_line_edge_right: " + key + " " + itos(edge_id) +
// " lot: " + itos(side.lot));
flecs::entity e = lookup(key);
struct CLine *cl = e.get_mut<CLine>();
cl->line.edges[edge_id].right = side;
e.modified<CLine>();
cl = e.get_mut<CLine>();
assert(cl->line.edges[edge_id].right.lot == side.lot);
}
struct RoadLinesData::road_edge_side
get_line_edge_left(const String &key, int edge_id) const
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.edges[edge_id].left;
}
struct RoadLinesData::road_edge_side
get_line_edge_right(const String &key, int edge_id) const
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.edges[edge_id].right;
}
inline struct RoadLinesData::road_line get_line(const String &key)
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line; return cl->line;
} }
inline const Transform &get_line_point_transform(const String &key,
int point_index)
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.points[point_index];
}
inline const Vector3 &get_line_point(const String &key, int point_index)
{
flecs::entity e = lookup(key);
const struct CLine *cl = e.get<CLine>();
return cl->line.points[point_index].origin;
}
inline const struct RoadLinesData::road_line & inline const struct RoadLinesData::road_line &
operator[](const String &key) const operator[](const String &key) const
{ {
@@ -99,6 +173,12 @@ public:
CLine *cl = e.get_mut<CLine>(); CLine *cl = e.get_mut<CLine>();
if (cl->line.edges.size() != cl->line.points.size() - 1) if (cl->line.edges.size() != cl->line.points.size() - 1)
cl->line.edges.resize(cl->line.points.size() - 1); cl->line.edges.resize(cl->line.points.size() - 1);
e.modified<CLine>();
}
void update_line(const String &key)
{
flecs::entity e = lookup_create(key);
e.modified<CLine>();
} }
inline void insert_line_point(const String &key, int index, inline void insert_line_point(const String &key, int index,
const Transform &xform) const Transform &xform)
@@ -294,6 +374,71 @@ RoadLinesData::get_line(const String &key) const
{ {
return ::lines[key]; return ::lines[key];
} }
const struct RoadLinesData::road_line *
RoadLinesData::get_line_ptr(const String &key) const
{
return ::lines.get_line_ptr(key);
}
RoadLinesData::road_edge RoadLinesData::get_line_edge(const String &key,
int edge) const
{
return ::lines.get_line_ptr(key)->edges[edge];
}
RoadLinesData::road_edge_side
RoadLinesData::get_line_edge_left(const String &key, int edge) const
{
return ::lines.get_line_edge_left(key, edge);
}
RoadLinesData::road_edge_side
RoadLinesData::get_line_edge_right(const String &key, int edge) const
{
return ::lines.get_line_edge_right(key, edge);
}
RoadLinesData::road_edge_side
RoadLinesData::get_line_edge_side(const String &key, int edge, int side) const
{
switch (side) {
case 0:
return get_line_edge_left(key, edge);
break;
case 1:
return get_line_edge_right(key, edge);
break;
default:
assert(false);
break;
}
assert(false);
/* should never happen */
return RoadLinesData::road_edge_side(get_line_edge(key, edge));
}
void RoadLinesData::set_line_edge_left(const String &key, int edge,
road_edge_side &side)
{
::lines.set_line_edge_left(key, edge, side);
assert(::lines.get_line_edge(key, edge).left.lot == side.lot);
}
void RoadLinesData::set_line_edge_right(const String &key, int edge,
road_edge_side &side)
{
::lines.set_line_edge_right(key, edge, side);
assert(::lines.get_line_edge(key, edge).right.lot == side.lot);
}
void RoadLinesData::set_line_edge(const String &key, int edge_id,
const road_edge &edge)
{
::lines.set_line_edge(key, edge_id, edge);
assert(::lines.get_line_edge(key, edge_id).left.lot == edge.left.lot);
assert(::lines.get_line_edge(key, edge_id).right.lot == edge.right.lot);
}
int RoadLinesData::get_line_edge_count(const String &key) const
{
return ::lines.get_line_edge_count(key);
}
const Vector3 &RoadLinesData::get_line_point(const String &key, int index) const
{
return ::lines.get_line_point(key, index);
}
const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const
{ {
return ::lines[key]; return ::lines[key];
@@ -307,6 +452,15 @@ void RoadLinesData::set_line(const String &key, const road_line &line)
{ {
::lines.set_line(key, line); ::lines.set_line(key, line);
} }
void RoadLinesData::update_line(const String &key)
{
::lines.update_line(key);
}
const Transform &RoadLinesData::get_line_point_transform(const String &key,
int index) const
{
return ::lines.get_line_point_transform(key, index);
}
bool RoadLinesData::has_line(const String &key) bool RoadLinesData::has_line(const String &key)
{ {
return ::lines.has(key); return ::lines.has(key);
@@ -446,6 +600,7 @@ void RoadLinesData::load_data()
::lines.get_key_list(&tkeys); ::lines.get_key_list(&tkeys);
assert(!tkeys.empty()); assert(!tkeys.empty());
} }
update_line_edges();
initialized = true; initialized = true;
} }
void RoadLinesData::save_data() void RoadLinesData::save_data()
@@ -895,3 +1050,40 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line,
print_verbose("data: " + (ret.operator String())); print_verbose("data: " + (ret.operator String()));
return ret; return ret;
} }
bool RoadLinesData::road_edge_side::test(
const struct RoadLinesData::test_edge &other)
{
float dst = Geometry::get_closest_distance_between_segments(
test_p[0], test_p[1], other.p0, other.p1);
if (dst < 4.0f) {
print_line("dst: " + String::num(dst));
print_line(test_p[0].operator String() + " " +
test_p[1].operator String());
print_line(other.p0.operator String() + " " +
other.p1.operator String());
print_line("index: " + itos(other.edge_index));
return false;
}
if (other.left.lot > 0) {
dst = Geometry::get_closest_distance_between_segments(
test_p[0], test_p[1], other.left.test_p[0],
other.left.test_p[1]);
if (dst < 4.0f)
return false;
}
if (other.right.lot > 0) {
dst = Geometry::get_closest_distance_between_segments(
test_p[0], test_p[1], other.right.test_p[0],
other.right.test_p[1]);
if (dst < 4.0f)
return false;
}
return true;
}
void RoadLinesData::road_edge_side::update_test_points(
const RoadLinesData::road_edge &edge)
{
test_p[1] = test_p[0] + normal * lot_depth;
}

View File

@@ -27,7 +27,15 @@ public:
}; };
public: public:
struct test_edge;
struct road_edge;
struct road_line;
struct road_edge_side { struct road_edge_side {
const RoadLinesData::road_edge &edge;
Vector3 normal;
Vector3 pmid[2];
Vector3 pside[2];
Vector3 test_p[2];
int transit_stop_count; int transit_stop_count;
String transit_stop_type; String transit_stop_type;
float transit_stop_offset; float transit_stop_offset;
@@ -45,6 +53,12 @@ public:
float lot_y_offset; float lot_y_offset;
float lot_y_rotation; float lot_y_rotation;
String lot_type; String lot_type;
float lot_depth;
/* calculated */
float lot_depth_eff;
public:
struct buildings { struct buildings {
String id; String id;
Vector3 offsets; Vector3 offsets;
@@ -97,6 +111,7 @@ public:
ret["sideroad_y_rotation"] = sideroad_y_rotation; ret["sideroad_y_rotation"] = sideroad_y_rotation;
ret["sideroad_type"] = sideroad_type; ret["sideroad_type"] = sideroad_type;
ret["lot"] = lot; ret["lot"] = lot;
ret["lot_depth"] = lot_depth;
ret["lot_offset"] = lot_offset; ret["lot_offset"] = lot_offset;
ret["lot_dir_offset"] = lot_dir_offset; ret["lot_dir_offset"] = lot_dir_offset;
ret["lot_y_offset"] = lot_y_offset; ret["lot_y_offset"] = lot_y_offset;
@@ -112,8 +127,9 @@ public:
ret["lot_buildings"] = lot_buildings; ret["lot_buildings"] = lot_buildings;
return ret; return ret;
} }
road_edge_side() road_edge_side(const RoadLinesData::road_edge &edge)
: transit_stop_count(0) : edge(edge)
, transit_stop_count(0)
, transit_stop_type("") , transit_stop_type("")
, transit_stop_offset(0.0f) , transit_stop_offset(0.0f)
, transit_stop_dir_offset(0.0f) , transit_stop_dir_offset(0.0f)
@@ -130,6 +146,7 @@ public:
, lot_y_offset(0.0f) , lot_y_offset(0.0f)
, lot_y_rotation(0.0f) , lot_y_rotation(0.0f)
, lot_type(String("")) , lot_type(String(""))
, lot_depth(100.0f)
, buildings{} , buildings{}
{ {
} }
@@ -151,6 +168,7 @@ public:
side.sideroad_y_rotation = dict["sideroad_y_rotation"]; side.sideroad_y_rotation = dict["sideroad_y_rotation"];
side.sideroad_type = dict["sideroad_type"]; side.sideroad_type = dict["sideroad_type"];
side.lot = dict["lot"]; side.lot = dict["lot"];
side.lot_depth = dict.get("lot_depth", 100.0f);
side.lot_offset = dict["lot_offset"]; side.lot_offset = dict["lot_offset"];
side.lot_dir_offset = dict["lot_dir_offset"]; side.lot_dir_offset = dict["lot_dir_offset"];
side.lot_y_offset = dict["lot_y_offset"]; side.lot_y_offset = dict["lot_y_offset"];
@@ -169,6 +187,118 @@ public:
parts[i]); parts[i]);
} }
} }
bool test(const struct RoadLinesData::test_edge &other);
void
update_test_points(const struct RoadLinesData::road_edge &edge);
struct RoadLinesData::road_edge_side &
operator=(const struct RoadLinesData::road_edge_side &other)
{
if (this == &other)
return *this;
from_dict(*this, other.to_dict());
pmid[0] = other.pmid[0];
pmid[1] = other.pmid[1];
pside[0] = other.pside[0];
pside[1] = other.pside[1];
normal = other.normal;
test_p[0] = other.test_p[0];
test_p[1] = other.test_p[1];
lot_depth_eff = other.lot_depth_eff;
return *this;
}
};
struct test_edge {
String line_key;
int edge_index;
int p0_index, p1_index;
Vector3 p0, p1;
struct road_edge_side left, right;
test_edge(const String &key, int index)
: line_key(key)
, edge_index(index)
, left(RoadLinesData::get_singleton()
->lines(key)
.edges[index])
, right(RoadLinesData::get_singleton()
->lines(key)
.edges[index])
{
update_from_line();
}
bool operator==(const struct test_edge &other)
{
return line_key == other.line_key &&
edge_index == other.edge_index;
}
void validate()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
RoadLinesData::road_edge edge =
rld->get_line_edge(line_key, edge_index);
if (edge.left.lot != left.lot) {
print_line("key: " + line_key +
" index: " + itos(edge_index));
print_line("rl.edges[edge_index].left.lot = " +
itos(edge.left.lot));
print_line("left.lot = " + itos(left.lot));
}
if (edge.right.lot != right.lot) {
print_line("key: " + line_key +
" index: " + itos(edge_index));
print_line("rl.edges[edge_index].right.lot = " +
itos(edge.right.lot));
print_line("right.lot = " + itos(right.lot));
}
assert(edge.left.lot == left.lot);
assert(edge.left.lot_depth == left.lot_depth);
assert(edge.right.lot == right.lot);
assert(edge.right.lot_depth == right.lot_depth);
}
void update_from_line()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
RoadLinesData::road_edge edge =
rld->get_line_edge(line_key, edge_index);
print_line("line: " + line_key +
" index: " + itos(edge_index) +
" left.lot: " + itos(edge.left.lot) +
" right.lot: " + itos(edge.right.lot));
print_line(edge.left.pmid[0].operator String());
print_line(edge.right.pmid[0].operator String());
assert(edge.left.pmid[0].is_equal_approx(
edge.right.pmid[0]));
assert(edge.left.pmid[1].is_equal_approx(
edge.right.pmid[1]));
left = edge.left;
right = edge.right;
left.normal = edge.left.normal;
left.lot = edge.left.lot;
left.lot_depth = edge.left.lot_depth;
right.normal = edge.right.normal;
right.lot = edge.right.lot;
right.lot_depth = edge.right.lot_depth;
validate();
}
void update_line()
{
print_line("update_line");
RoadLinesData *rld = RoadLinesData::get_singleton();
RoadLinesData::road_edge_side tmp_left =
rld->get_line_edge_left(line_key, edge_index);
RoadLinesData::road_edge_side tmp_right =
rld->get_line_edge_right(line_key, edge_index);
tmp_left.lot = left.lot;
tmp_left.lot_depth = left.lot_depth;
tmp_right.lot = right.lot;
tmp_right.lot_depth = right.lot_depth;
rld->set_line_edge_left(line_key, edge_index, tmp_left);
rld->set_line_edge_right(line_key, edge_index,
tmp_right);
validate();
rld->update_line_edges();
validate();
}
}; };
struct road_edge { struct road_edge {
struct road_edge_side left, right; struct road_edge_side left, right;
@@ -188,10 +318,18 @@ public:
road_edge_side::from_dict(edge.left, dleft); road_edge_side::from_dict(edge.left, dleft);
road_edge_side::from_dict(edge.right, dright); road_edge_side::from_dict(edge.right, dright);
} }
road_edge()
: left(*this)
, right(*this)
{
}
}; };
struct road_line { struct road_line {
std::vector<Transform> points; std::vector<Transform> points;
std::vector<struct road_edge> edges; std::vector<struct road_edge> edges;
public:
std::vector<struct line_segment> segments; std::vector<struct line_segment> segments;
int lanes; int lanes;
int pattern; int pattern;
@@ -202,6 +340,50 @@ public:
struct road_line_index { struct road_line_index {
std::vector<int> indices; std::vector<int> indices;
}; };
void update_line_edges()
{
int edge_index;
List<String> keys;
get_road_lines_key_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
String key = e->get();
// struct road_line rl = get_line(key);
for (edge_index = 0;
edge_index < get_line_edge_count(key);
edge_index++) {
const Vector3 &p0 =
get_line_point(key, edge_index);
const Vector3 &p1 =
get_line_point(key, edge_index + 1);
Vector3 dir = (p1 - p0).normalized();
Vector3 d = dir;
Vector3 left_n = Vector3(0, 1, 0).cross(d);
Vector3 right_n = -left_n;
RoadLinesData::road_edge tmp_edge =
get_line_edge(key, edge_index);
tmp_edge.left.normal = left_n;
tmp_edge.right.normal = right_n;
tmp_edge.left.pmid[0] = p0;
tmp_edge.left.pmid[1] = p1;
tmp_edge.right.pmid[0] = p0;
tmp_edge.right.pmid[1] = p1;
tmp_edge.left.test_p[0] = p0 + (p1 - p0) * 0.5f;
tmp_edge.left.test_p[1] =
tmp_edge.left.test_p[0] +
tmp_edge.left.normal *
tmp_edge.left.lot_depth;
tmp_edge.right.test_p[0] =
p0 + (p1 - p0) * 0.5f;
tmp_edge.right.test_p[1] =
tmp_edge.right.test_p[0] +
tmp_edge.right.normal *
tmp_edge.right.lot_depth;
set_line_edge(key, edge_index, tmp_edge);
}
e = e->next();
}
}
public: public:
static ImmediateGeometry *get_debug_node(); static ImmediateGeometry *get_debug_node();
@@ -214,6 +396,25 @@ public:
const struct road_line &lines(const String &key) const; const struct road_line &lines(const String &key) const;
const struct road_line_index &indices(const String &key) const; const struct road_line_index &indices(const String &key) const;
void set_line(const String &key, const struct road_line &line); void set_line(const String &key, const struct road_line &line);
void update_line(const String &key);
const struct road_line *get_line_ptr(const String &key) const;
struct road_edge get_line_edge(const String &key, int edge) const;
struct road_edge_side get_line_edge_left(const String &key,
int edge) const;
struct road_edge_side get_line_edge_right(const String &key,
int edge) const;
struct road_edge_side get_line_edge_side(const String &key, int edge,
int side) const;
void set_line_edge_left(const String &key, int edge,
struct road_edge_side &side);
void set_line_edge_right(const String &key, int edge,
struct road_edge_side &side);
void set_line_edge(const String &key, int edge_id,
const struct road_edge &edge);
int get_line_edge_count(const String &key) const;
const Vector3 &get_line_point(const String &key, int index) const;
const Transform &get_line_point_transform(const String &key,
int index) const;
bool has_line(const String &key); bool has_line(const String &key);
void insert_line_point(const String &key, int index, void insert_line_point(const String &key, int index,
const Transform &xform); const Transform &xform);

View File

@@ -589,6 +589,7 @@ void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
assert(rld->has_line(line_name)); assert(rld->has_line(line_name));
update_line_index_ui(); update_line_index_ui();
update_ui(); update_ui();
rld->update_line_edges();
} }
void RoadLinesEditor::delete_current_line() void RoadLinesEditor::delete_current_line()
@@ -599,6 +600,7 @@ void RoadLinesEditor::delete_current_line()
rld->erase_line(delete_line); rld->erase_line(delete_line);
update_line_index_ui(); update_line_index_ui();
update_ui(); update_ui();
rld->update_line_edges();
} }
Vector3 RoadLinesEditor::get_cursor_position() Vector3 RoadLinesEditor::get_cursor_position()
@@ -1027,6 +1029,7 @@ void RoadLinesEditor::event_handler(const String &event,
} }
RoadLinesData::road_edge::from_dict(rl.edges[index], data); RoadLinesData::road_edge::from_dict(rl.edges[index], data);
rld->set_line(current_line, rl); rld->set_line(current_line, rl);
rld->update_line_edges();
print_line("Update for index: " + itos(index) + " done"); print_line("Update for index: " + itos(index) + " done");
} }
} }
@@ -1199,8 +1202,10 @@ class EdgeEditorHandler {
void set_lot(RoadLinesData::road_edge_side &side, const String &pname, void set_lot(RoadLinesData::road_edge_side &side, const String &pname,
float dir_offt) float dir_offt)
{ {
print_line("set_lot");
side.lot_type = pname.replace("lot-", ""); side.lot_type = pname.replace("lot-", "");
if (side.lot == 0) { if (side.lot == 0) {
print_line("set_lot 2");
side.lot = 1; side.lot = 1;
side.lot_offset = get_edge_conf<float>(pname, "left", side.lot_offset = get_edge_conf<float>(pname, "left",
"lot_offset"); "lot_offset");
@@ -1278,7 +1283,6 @@ class EdgeEditorHandler {
b.id = pname; b.id = pname;
b.offsets = Vector3(); b.offsets = Vector3();
b.y_rotation = 0.0f; b.y_rotation = 0.0f;
rl.edges[index].left.buildings.push_back(b); rl.edges[index].left.buildings.push_back(b);
if (rl.edges[index].left.lot > 0) { if (rl.edges[index].left.lot > 0) {
String lot_id = String lot_id =
@@ -1307,6 +1311,8 @@ class EdgeEditorHandler {
rl.edges[index].right.buildings.clear(); rl.edges[index].right.buildings.clear();
} }
rld->set_line(current_line, rl); rld->set_line(current_line, rl);
print_line("line updated: " + current_line);
rld->update_line_edges();
editor->rebuild_roads(); editor->rebuild_roads();
} else if (event == "road_lines_edge_editor::menu::right") { } else if (event == "road_lines_edge_editor::menu::right") {
PopupMenu *menu = Object::cast_to<PopupMenu>(args[0]); PopupMenu *menu = Object::cast_to<PopupMenu>(args[0]);
@@ -1358,6 +1364,8 @@ class EdgeEditorHandler {
rl.edges[index].right.buildings.clear(); rl.edges[index].right.buildings.clear();
} }
rld->set_line(current_line, rl); rld->set_line(current_line, rl);
rld->update_line_edges();
print_line("line updated: " + current_line);
editor->rebuild_roads(); editor->rebuild_roads();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,6 @@ void BuildingLayoutGraphUI::menu_pressed(int id, Control *button,
const String &path) const String &path)
{ {
assert(button); assert(button);
print_line(itos(id));
print_line(path); print_line(path);
switch (id) { switch (id) {
case 100: case 100:
@@ -459,7 +458,6 @@ static void *__PPP_ptr2 = nullptr;
void BuildingLayoutGraphUI::command_entered(int index, Control *item, void BuildingLayoutGraphUI::command_entered(int index, Control *item,
const String &path) const String &path)
{ {
print_line(itos(index));
flecs::world ecs = BaseData::get_singleton()->get(); flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup(path.ascii().ptr()); flecs::entity e = ecs.lookup(path.ascii().ptr());
assert(e.is_valid()); assert(e.is_valid());