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,
2,
3,
4
4,
5,
6
]
}
],
@@ -47,27 +49,34 @@
"mesh":3,
"name":"roadd-sidewalk_end",
"translation":[
3.3000001907348633,
4.8000006675720215,
0,
0
]
},
{
"mesh":4,
"name":"roadd-sidewalk_start",
"rotation":[
0,
0,
-1,
0
],
"scale":[
-1,
-1,
-1
],
"name":"road-lane-sidwalk-sideroad",
"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
]
@@ -78,9 +87,9 @@
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
0.118567882488869,
0.118567882488869,
0.118567882488869
]
},
"KHR_materials_ior":{
@@ -92,7 +101,10 @@
"baseColorTexture":{
"index":0
},
"metallicFactor":0.20000000298023224
"metallicFactor":0.05000000074505806,
"metallicRoughnessTexture":{
"index":1
}
}
}
],
@@ -140,7 +152,7 @@
]
},
{
"name":"road-sidewalk.001",
"name":"road-sidewalk-end",
"primitives":[
{
"attributes":{
@@ -154,7 +166,7 @@
]
},
{
"name":"road-sidewalk.006",
"name":"road-sidewalk-sideroad",
"primitives":[
{
"attributes":{
@@ -162,7 +174,36 @@
"NORMAL":17,
"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
}
]
@@ -172,6 +213,10 @@
{
"sampler":0,
"source":0
},
{
"sampler":0,
"source":1
}
],
"images":[
@@ -179,6 +224,11 @@
"mimeType":"image/png",
"name":"road",
"uri":"road.png"
},
{
"mimeType":"image/png",
"name":"roughness",
"uri":"roughness.png"
}
],
"accessors":[
@@ -187,12 +237,12 @@
"componentType":5126,
"count":32,
"max":[
-8.847564458847046e-09,
0.12099996209144592,
0,
0.12867334485054016,
5.960464477539063e-08
],
"min":[
-0.9999999403953552,
-1,
-0.09999995678663254,
-0.5
],
@@ -219,11 +269,11 @@
{
"bufferView":4,
"componentType":5126,
"count":74,
"count":76,
"max":[
9.921204764395952e-07,
0.1214386522769928,
-6.735790520906448e-07
1.0132789611816406e-06,
0.12219604849815369,
-6.705522537231445e-07
],
"min":[
-0.9999990463256836,
@@ -235,13 +285,13 @@
{
"bufferView":5,
"componentType":5126,
"count":74,
"count":76,
"type":"VEC3"
},
{
"bufferView":6,
"componentType":5126,
"count":74,
"count":76,
"type":"VEC2"
},
{
@@ -253,9 +303,9 @@
{
"bufferView":8,
"componentType":5126,
"count":40,
"count":42,
"max":[
2.5033950805664062e-05,
0.0032810475677251816,
0.19999995827674866,
0
],
@@ -269,13 +319,13 @@
{
"bufferView":9,
"componentType":5126,
"count":40,
"count":42,
"type":"VEC3"
},
{
"bufferView":10,
"componentType":5126,
"count":40,
"count":42,
"type":"VEC2"
},
{
@@ -287,64 +337,145 @@
{
"bufferView":12,
"componentType":5126,
"count":418,
"count":433,
"max":[
0.00867057777941227,
0.008670568466186523,
0.19999998807907104,
0
2.6469779601696886e-23
],
"min":[
-1.100000023841858,
-0.10000000149011612,
-0.5000007152557373
-1.1999990940093994,
-0.10000000894069672,
-0.5
],
"type":"VEC3"
},
{
"bufferView":13,
"componentType":5126,
"count":418,
"count":433,
"type":"VEC3"
},
{
"bufferView":14,
"componentType":5126,
"count":418,
"count":433,
"type":"VEC2"
},
{
"bufferView":15,
"componentType":5123,
"count":975,
"count":972,
"type":"SCALAR"
},
{
"bufferView":16,
"componentType":5126,
"count":418,
"count":29,
"max":[
0.00867057777941227,
0.19999998807907104,
0.5
0.008670799434185028,
0.12041480839252472,
5.960464477539063e-08
],
"min":[
-1.100000023841858,
-0.10000000149011612,
-7.152557373046875e-07
-1.1999988555908203,
-0.09999999403953552,
-0.5
],
"type":"VEC3"
},
{
"bufferView":17,
"componentType":5126,
"count":418,
"count":29,
"type":"VEC3"
},
{
"bufferView":18,
"componentType":5126,
"count":418,
"count":29,
"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":[
@@ -374,93 +505,153 @@
},
{
"buffer":0,
"byteLength":888,
"byteLength":912,
"byteOffset":1120,
"target":34962
},
{
"buffer":0,
"byteLength":888,
"byteOffset":2008,
"byteLength":912,
"byteOffset":2032,
"target":34962
},
{
"buffer":0,
"byteLength":592,
"byteOffset":2896,
"byteLength":608,
"byteOffset":2944,
"target":34962
},
{
"buffer":0,
"byteLength":252,
"byteOffset":3488,
"byteOffset":3552,
"target":34963
},
{
"buffer":0,
"byteLength":480,
"byteOffset":3740,
"byteLength":504,
"byteOffset":3804,
"target":34962
},
{
"buffer":0,
"byteLength":480,
"byteOffset":4220,
"byteLength":504,
"byteOffset":4308,
"target":34962
},
{
"buffer":0,
"byteLength":320,
"byteOffset":4700,
"byteLength":336,
"byteOffset":4812,
"target":34962
},
{
"buffer":0,
"byteLength":132,
"byteOffset":5020,
"byteOffset":5148,
"target":34963
},
{
"buffer":0,
"byteLength":5016,
"byteOffset":5152,
"byteLength":5196,
"byteOffset":5280,
"target":34962
},
{
"buffer":0,
"byteLength":5016,
"byteOffset":10168,
"byteLength":5196,
"byteOffset":10476,
"target":34962
},
{
"buffer":0,
"byteLength":3344,
"byteOffset":15184,
"byteLength":3464,
"byteOffset":15672,
"target":34962
},
{
"buffer":0,
"byteLength":1950,
"byteOffset":18528,
"byteLength":1944,
"byteOffset":19136,
"target":34963
},
{
"buffer":0,
"byteLength":5016,
"byteOffset":20480,
"byteLength":348,
"byteOffset":21080,
"target":34962
},
{
"buffer":0,
"byteLength":5016,
"byteOffset":25496,
"byteLength":348,
"byteOffset":21428,
"target":34962
},
{
"buffer":0,
"byteLength":3344,
"byteOffset":30512,
"byteLength":232,
"byteOffset":21776,
"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":[
@@ -471,7 +662,7 @@
],
"buffers":[
{
"byteLength":33856,
"byteLength":50364,
"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"
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={
"vram_texture": false
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
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]
compress/mode=0
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/repeat=true
flags/filter=true
flags/mipmaps=false
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
@@ -31,5 +33,5 @@ process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
detect_3d=false
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"
mid_mesh = "res://astream/road/road-lanes_road-lane-mid.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]
road_lines_path = "res://astream/road_lines.json"
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=["event"])
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
SConscript("buildings/SCsub")
@@ -18,6 +17,7 @@ SConscript("rtree/SCsub")
SConscript("ui/SCsub")
SConscript("npc/SCsub")
SConscript("event/SCsub")
SConscript("flecs/SCsub")

View File

@@ -181,7 +181,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
while (e) {
struct building b;
String key = e->get();
if (!key.begins_with("road::")) {
if (!key.begins_with("road::") && !key.begins_with("road__")) {
Dictionary entry = json[key];
String id = entry.get("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) {
String key = b.building.key;
/* 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();
dict["index"] = index;
json[key] = dict;
@@ -712,7 +712,6 @@ const struct BuildingsData::building &
BuildingsData::get_building(const String &building_key) const
{
String ename = "base:" + building_key;
print_line("get_building: " + ename);
flecs::entity e = lookup(ename);
assert(e.is_valid());
return e.get<CBuildingData>()->building;
@@ -722,7 +721,6 @@ struct BuildingsData::building &
BuildingsData::get_building(const String &building_key)
{
String ename = "base:" + building_key;
print_line("get_building: " + ename);
flecs::entity e = lookup(ename);
assert(e.is_valid());
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>();
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);
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;
}
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 &
operator[](const String &key) const
{
@@ -99,6 +173,12 @@ public:
CLine *cl = e.get_mut<CLine>();
if (cl->line.edges.size() != 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,
const Transform &xform)
@@ -294,6 +374,71 @@ RoadLinesData::get_line(const String &key) const
{
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
{
return ::lines[key];
@@ -307,6 +452,15 @@ void RoadLinesData::set_line(const String &key, const road_line &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)
{
return ::lines.has(key);
@@ -446,6 +600,7 @@ void RoadLinesData::load_data()
::lines.get_key_list(&tkeys);
assert(!tkeys.empty());
}
update_line_edges();
initialized = true;
}
void RoadLinesData::save_data()
@@ -895,3 +1050,40 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line,
print_verbose("data: " + (ret.operator String()));
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:
struct test_edge;
struct road_edge;
struct road_line;
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;
String transit_stop_type;
float transit_stop_offset;
@@ -45,6 +53,12 @@ public:
float lot_y_offset;
float lot_y_rotation;
String lot_type;
float lot_depth;
/* calculated */
float lot_depth_eff;
public:
struct buildings {
String id;
Vector3 offsets;
@@ -97,6 +111,7 @@ public:
ret["sideroad_y_rotation"] = sideroad_y_rotation;
ret["sideroad_type"] = sideroad_type;
ret["lot"] = lot;
ret["lot_depth"] = lot_depth;
ret["lot_offset"] = lot_offset;
ret["lot_dir_offset"] = lot_dir_offset;
ret["lot_y_offset"] = lot_y_offset;
@@ -112,8 +127,9 @@ public:
ret["lot_buildings"] = lot_buildings;
return ret;
}
road_edge_side()
: transit_stop_count(0)
road_edge_side(const RoadLinesData::road_edge &edge)
: edge(edge)
, transit_stop_count(0)
, transit_stop_type("")
, transit_stop_offset(0.0f)
, transit_stop_dir_offset(0.0f)
@@ -130,6 +146,7 @@ public:
, lot_y_offset(0.0f)
, lot_y_rotation(0.0f)
, lot_type(String(""))
, lot_depth(100.0f)
, buildings{}
{
}
@@ -151,6 +168,7 @@ public:
side.sideroad_y_rotation = dict["sideroad_y_rotation"];
side.sideroad_type = dict["sideroad_type"];
side.lot = dict["lot"];
side.lot_depth = dict.get("lot_depth", 100.0f);
side.lot_offset = dict["lot_offset"];
side.lot_dir_offset = dict["lot_dir_offset"];
side.lot_y_offset = dict["lot_y_offset"];
@@ -169,6 +187,118 @@ public:
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_side left, right;
@@ -188,10 +318,18 @@ public:
road_edge_side::from_dict(edge.left, dleft);
road_edge_side::from_dict(edge.right, dright);
}
road_edge()
: left(*this)
, right(*this)
{
}
};
struct road_line {
std::vector<Transform> points;
std::vector<struct road_edge> edges;
public:
std::vector<struct line_segment> segments;
int lanes;
int pattern;
@@ -202,6 +340,50 @@ public:
struct road_line_index {
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:
static ImmediateGeometry *get_debug_node();
@@ -214,6 +396,25 @@ public:
const struct road_line &lines(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 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);
void insert_line_point(const String &key, int index,
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));
update_line_index_ui();
update_ui();
rld->update_line_edges();
}
void RoadLinesEditor::delete_current_line()
@@ -599,6 +600,7 @@ void RoadLinesEditor::delete_current_line()
rld->erase_line(delete_line);
update_line_index_ui();
update_ui();
rld->update_line_edges();
}
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);
rld->set_line(current_line, rl);
rld->update_line_edges();
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,
float dir_offt)
{
print_line("set_lot");
side.lot_type = pname.replace("lot-", "");
if (side.lot == 0) {
print_line("set_lot 2");
side.lot = 1;
side.lot_offset = get_edge_conf<float>(pname, "left",
"lot_offset");
@@ -1278,7 +1283,6 @@ class EdgeEditorHandler {
b.id = pname;
b.offsets = Vector3();
b.y_rotation = 0.0f;
rl.edges[index].left.buildings.push_back(b);
if (rl.edges[index].left.lot > 0) {
String lot_id =
@@ -1307,6 +1311,8 @@ class EdgeEditorHandler {
rl.edges[index].right.buildings.clear();
}
rld->set_line(current_line, rl);
print_line("line updated: " + current_line);
rld->update_line_edges();
editor->rebuild_roads();
} else if (event == "road_lines_edge_editor::menu::right") {
PopupMenu *menu = Object::cast_to<PopupMenu>(args[0]);
@@ -1358,6 +1364,8 @@ class EdgeEditorHandler {
rl.edges[index].right.buildings.clear();
}
rld->set_line(current_line, rl);
rld->update_line_edges();
print_line("line updated: " + current_line);
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)
{
assert(button);
print_line(itos(id));
print_line(path);
switch (id) {
case 100:
@@ -459,7 +458,6 @@ static void *__PPP_ptr2 = nullptr;
void BuildingLayoutGraphUI::command_entered(int index, Control *item,
const String &path)
{
print_line(itos(index));
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup(path.ascii().ptr());
assert(e.is_valid());