Updated generation of lots

This commit is contained in:
2025-03-03 10:00:13 +03:00
parent fc1c4b5168
commit 2afa4feee8
8 changed files with 622 additions and 287 deletions

View File

@@ -3327,14 +3327,14 @@
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"sideroad_type": "",
"lot": 1,
"lot_depth": 46,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_type": "",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
@@ -3348,14 +3348,14 @@
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"sideroad_type": "",
"lot": 1,
"lot_depth": 9.663863,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_type": "",
"lot_buildings": ":0, 0, 0:0"
}
},
@@ -3371,14 +3371,14 @@
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"sideroad_type": "",
"lot": 1,
"lot_depth": 52.253078,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_type": "",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
@@ -3392,14 +3392,14 @@
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"sideroad_type": "",
"lot": 1,
"lot_depth": 86.428551,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_type": "",
"lot_buildings": ":0, 0, 0:0"
}
}
@@ -4373,7 +4373,7 @@
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 1,
"lot_depth": 58.483521,
"lot_depth": 58.498596,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
@@ -4737,9 +4737,9 @@
"points": [
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -740, 0.036499, -560 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -735, 0.0276184, -595 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -715, 0.0155029, -750 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -710, 0.0388794, -800 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -670, 0.0308838, -800 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -728, 0.000350952, -752 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -712, 0.000152588, -790 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -670, 0.000167847, -804 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -445, 0.0236511, -805 )",
"Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -320, 0.0359802, -805 )"
],
@@ -4778,8 +4778,8 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 74.268272,
"lot": 1,
"lot_depth": 73.84967,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
@@ -4822,8 +4822,8 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 80.475876,
"lot": 1,
"lot_depth": 100,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
@@ -4866,8 +4866,8 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 17.667665,
"lot": 1,
"lot_depth": 40.091198,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
@@ -4899,29 +4899,6 @@
"lot_buildings": ":0, 0, 0:0"
},
"right": {
"transit_stop_count": 0,
"transit_stop_type": "",
"transit_stop_offset": 0,
"transit_stop_dir_offset": 0,
"transit_stop_y_rotation": 0,
"sideroad": 0,
"sideroad_offset": 0,
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 20.278347,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_buildings": ":0, 0, 0:0"
}
},
{
"left": {
"transit_stop_count": 0,
"transit_stop_type": "",
"transit_stop_offset": 0,
@@ -4934,28 +4911,7 @@
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 1,
"lot_depth": 38.619808,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
"transit_stop_count": 0,
"transit_stop_type": "",
"transit_stop_offset": 0,
"transit_stop_dir_offset": 0,
"transit_stop_y_rotation": 0,
"sideroad": 0,
"sideroad_offset": 0,
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 74.593224,
"lot_depth": 49.743282,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
@@ -4998,7 +4954,51 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot": 1,
"lot_depth": 61.328331,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_buildings": ":0, 0, 0:0"
}
},
{
"left": {
"transit_stop_count": 0,
"transit_stop_type": "",
"transit_stop_offset": 0,
"transit_stop_dir_offset": 0,
"transit_stop_y_rotation": 0,
"sideroad": 0,
"sideroad_offset": 0,
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 1,
"lot_depth": 100,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,
"lot_y_rotation": 0,
"lot_type": "Null",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
"transit_stop_count": 0,
"transit_stop_type": "",
"transit_stop_offset": 0,
"transit_stop_dir_offset": 0,
"transit_stop_y_rotation": 0,
"sideroad": 0,
"sideroad_offset": 0,
"sideroad_dir_offset": 0,
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 1,
"lot_depth": 12.020815,
"lot_offset": 0,
"lot_dir_offset": 0,
@@ -7407,7 +7407,7 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot": 1,
"lot_depth": 100,
"lot_offset": 0,
"lot_dir_offset": 0,
@@ -7451,7 +7451,7 @@
"sideroad_y_offset": 0,
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot": 1,
"lot_depth": 100,
"lot_offset": 0,
"lot_dir_offset": 0,
@@ -11413,7 +11413,7 @@
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 0,
"lot_depth": 73.214561,
"lot_depth": 72.343361,
"lot_offset": 0,
"lot_dir_offset": 0,
"lot_y_offset": 0,

View File

@@ -61,6 +61,7 @@ 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"
lot_depth = 200.0
[lines]
road_lines_path = "res://astream/road_lines.json"
gen_prefixes = ["empty", "foundation30", "foundation60", "sideroad-start",

View File

@@ -0,0 +1,30 @@
#include <core/object.h>
#include "contours.h"
Contours *Contours::singleton = nullptr;
Contours *Contours::get_singleton()
{
if (!singleton)
singleton = memnew(Contours);
return singleton;
}
Contours::Contours()
{
}
Contours::~Contours()
{
}
bool Contours::is_in_closed_contour(const struct wedge *w)
{
int i, j;
bool found = false;
for (i = 0; i < (int)wedge_contours.size(); i++)
for (j = 0; j < (int)wedge_contours[i].size(); j++)
if (wedge_contours[i][j] == w)
return true;
return false;
}

View File

@@ -0,0 +1,15 @@
/* ~/godot-projects/streaming_world/src/modules/stream/contours.h */
#ifndef CONTOURS_H_
#define CONTOURS_H_
#include <vector>
struct Contours {
std::vector<std::vector<struct wedge *> > wedge_contours;
static Contours *singleton;
static Contours *get_singleton();
Contours();
virtual ~Contours();
bool is_in_closed_contour(const struct wedge *w);
};
#endif // CONTOURS_H_

View File

@@ -23,6 +23,9 @@ struct CLine {
struct CLineIndex {
struct RoadLinesData::road_line_index index;
};
struct CLineEdges {
std::vector<struct RoadLinesData::road_edge> edges;
};
class LinesAccessor;
struct CLinesCommon {
Node *debug;
@@ -97,22 +100,22 @@ public:
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];
const struct CLineEdges *cl = e.get<CLineEdges>();
return cl->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>();
struct CLineEdges *cl = e.get_mut<CLineEdges>();
cl->edges[edge_id] = edge;
e.modified<CLineEdges>();
}
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();
const struct CLineEdges *cl = e.get<CLineEdges>();
return cl->edges.size();
}
void
set_line_edge_left(const String &key, int edge_id,
@@ -121,11 +124,11 @@ public:
// 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);
struct CLineEdges *cl = e.get_mut<CLineEdges>();
cl->edges[edge_id].left = side;
e.modified<CLineEdges>();
cl = e.get_mut<CLineEdges>();
assert(cl->edges[edge_id].left.lot == side.lot);
}
void
set_line_edge_right(const String &key, int edge_id,
@@ -134,25 +137,25 @@ public:
// 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 CLineEdges *cl = e.get_mut<CLineEdges>();
cl->edges[edge_id].right = side;
e.modified<CLineEdges>();
cl = e.get_mut<CLineEdges>();
assert(cl->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;
const struct CLineEdges *cl = e.get<CLineEdges>();
return cl->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;
const struct CLineEdges *cl = e.get<CLineEdges>();
return cl->edges[edge_id].right;
}
inline struct RoadLinesData::road_line get_line(const String &key)
{
@@ -184,12 +187,19 @@ public:
inline void set_line(const String &key,
const struct RoadLinesData::road_line &line)
{
flecs::entity e = lookup_create(key);
flecs::entity e;
if (!has(key))
e = lookup_create(key);
else
e = lookup(key);
e.set<CLine>({ line });
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.emplace<CLineEdges>();
CLineEdges *cle = e.get_mut<CLineEdges>();
const CLine *cl = e.get<CLine>();
if (cle->edges.size() != cl->line.points.size() - 1)
cle->edges.resize(cl->line.points.size() - 1);
e.modified<CLine>();
e.modified<CLineEdges>();
}
void update_line(const String &key)
{
@@ -201,17 +211,23 @@ public:
{
flecs::entity e = lookup(key);
struct CLine *cl = e.get_mut<CLine>();
struct CLineEdges *cle = e.get_mut<CLineEdges>();
cl->line.points.insert(cl->line.points.begin() + index, xform);
if (cl->line.edges.size() != cl->line.points.size() - 1)
cl->line.edges.resize(cl->line.points.size() - 1);
if (cle->edges.size() != cl->line.points.size() - 1)
cle->edges.resize(cl->line.points.size() - 1);
e.modified<CLine>();
e.modified<CLineEdges>();
}
inline void erase_line_point(const String &key, int index)
{
flecs::entity e = lookup(key);
struct CLine *cl = e.get_mut<CLine>();
struct CLineEdges *cle = e.get_mut<CLineEdges>();
cl->line.points.erase(cl->line.points.begin() + index);
if (cl->line.edges.size() != cl->line.points.size() - 1)
cl->line.edges.resize(cl->line.points.size() - 1);
if (cle->edges.size() != cl->line.points.size() - 1)
cle->edges.resize(cl->line.points.size() - 1);
e.modified<CLine>();
e.modified<CLineEdges>();
}
inline void set_line_point_position(const String &key, int index,
const Vector3 &position)
@@ -416,13 +432,13 @@ RoadLinesData::get_line_ptr(const String &key) const
const LinesAccessor *lines = root_e.get<LinesAccessor>();
return lines->get_line_ptr(key);
}
RoadLinesData::road_edge RoadLinesData::get_line_edge(const String &key,
int edge) const
const RoadLinesData::road_edge &RoadLinesData::get_line_edge(const String &key,
int edge) const
{
flecs::entity root_e = BaseData::get_singleton()->get().lookup("lines");
assert(root_e.is_valid());
const LinesAccessor *lines = root_e.get<LinesAccessor>();
return lines->get_line_ptr(key)->edges[edge];
return lines->get_line_edge(key, edge);
}
RoadLinesData::road_edge_side
RoadLinesData::get_line_edge_left(const String &key, int edge) const
@@ -702,18 +718,19 @@ void RoadLinesData::load_data()
int pattern = entry.get("pattern", -1);
rline.pattern = pattern;
rline.points.resize(points.size());
rline.edges.resize(edges.size());
for (i = 0; i < (int)points.size(); i++) {
String point_s = points[i];
rline.points[i] = from_string<Transform>(point_s);
}
for (i = 0; i < (int)edges.size(); i++) {
const Dictionary &d = edges[i];
rline.edges[i].from_dict(rline.edges[i], d);
}
// TODO: wtf is flags?
rline.lanes = lanes;
set_line(key, rline);
for (i = 0; i < (int)edges.size(); i++) {
const Dictionary &d = edges[i];
RoadLinesData::road_edge edge;
edge.from_dict(edge, d);
set_line_edge(key, i, edge);
}
RoadLinesData::road_line_index index;
line_indices.set_index(key, index);
e = e->next();
@@ -747,14 +764,13 @@ void RoadLinesData::save_data()
Dictionary pvalues;
Array points, edges, indices;
points.resize(lines->get_line(e->get()).points.size());
edges.resize(lines->get_line(e->get()).edges.size());
edges.resize(lines->get_line_edge_count(e->get()));
for (i = 0; i < (int)lines->get_line(e->get()).points.size();
i++)
points[i] =
to_string(lines->get_line(e->get()).points[i]);
for (i = 0; i < (int)lines->get_line(e->get()).edges.size();
i++)
edges[i] = lines->get_line(e->get()).edges[i].to_dict();
for (i = 0; i < (int)lines->get_line_edge_count(e->get()); i++)
edges[i] = lines->get_line_edge(e->get(), i).to_dict();
indices.resize(this->indices(e->get()).indices.size());
for (i = 0; i < (int)this->indices(e->get()).indices.size();
i++)

View File

@@ -205,6 +205,7 @@ public:
test_p[0] = other.test_p[0];
test_p[1] = other.test_p[1];
lot_depth_eff = other.lot_depth_eff;
lot_points = other.lot_points;
return *this;
}
};
@@ -217,12 +218,10 @@ public:
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])
, left(RoadLinesData::get_singleton()->get_line_edge(
key, index))
, right(RoadLinesData::get_singleton()->get_line_edge(
key, index))
{
update_from_line();
}
@@ -328,8 +327,6 @@ public:
struct road_line {
std::vector<Transform> points;
std::vector<struct road_edge> edges;
public:
std::vector<struct line_segment> segments;
int lanes;
@@ -399,7 +396,8 @@ public:
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;
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,

View File

@@ -1020,15 +1020,19 @@ void RoadLinesEditor::event_handler(const String &event,
const Dictionary &data = args[1];
print_line("Update for index: " + itos(index));
print_line("Update: " + to_string(data));
RoadLinesData::road_line rl = rld->get_line(current_line);
if (index < 0 || index >= (int)rl.edges.size()) {
// RoadLinesData::road_line rl = rld->get_line(current_line);
if (index < 0 ||
index >= (int)rld->get_line_edge_count(current_line)) {
print_error("Invalid index: " + itos(index));
print_error("Edge count: " +
itos((int)rl.edges.size()));
itos((int)rld->get_line_edge_count(
current_line)));
return;
}
RoadLinesData::road_edge::from_dict(rl.edges[index], data);
rld->set_line(current_line, rl);
RoadLinesData::road_edge edge;
RoadLinesData::road_edge::from_dict(edge, data);
// rld->set_line(current_line, rl);
rld->set_line_edge(current_line, index, edge);
rld->update_line_edges();
print_line("Update for index: " + itos(index) + " done");
}
@@ -1272,43 +1276,62 @@ class EdgeEditorHandler {
rld->get_line(current_line);
String pname = get_pname(menu, id);
if (pname.begins_with("lot-")) {
RoadLinesData::road_edge_side side =
rld->get_line_edge_left(current_line,
index);
float dir_offt =
rl.points[index + 1].origin.distance_to(
rl.points[index].origin) /
2.0f;
set_lot(rl.edges[index].left, pname, dir_offt);
} else if (pname.begins_with("residental-")) {
set_lot(side, pname, dir_offt);
rld->set_line_edge_left(current_line, index,
side);
} else if (pname.begins_with("residental-") ||
pname.begins_with("business-")) {
RoadLinesData::road_edge_side side =
rld->get_line_edge_left(current_line,
index);
struct RoadLinesData::road_edge_side::buildings
b;
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 =
rl.edges[index].left.lot_type;
if (rl.edges[index]
.left.buildings.size() >
1) {
side.buildings.push_back(b);
if (side.lot > 0) {
String lot_id = side.lot_type;
if (side.buildings.size() > 1) {
const AABB &aabb_lot =
BuildingsData::get_singleton()
->building_aabbs
["lot-" +
lot_id];
bool pack_result = pack_buildings(
aabb_lot,
rl.edges[index]
.left.buildings,
2.0f);
bool pack_result =
pack_buildings(
aabb_lot,
side.buildings,
2.0f);
assert(pack_result);
}
}
rld->set_line_edge_left(current_line, index,
side);
} else if (pname == "clear") {
rl.edges[index].left.lot_type = "";
rl.edges[index].left.lot = 0;
rl.edges[index].left.buildings.clear();
RoadLinesData::road_edge_side side =
rld->get_line_edge_left(current_line,
index);
side.lot_type = "";
side.lot = 0;
side.buildings.clear();
rld->set_line_edge_left(current_line, index,
side);
} else if (pname == "clear-buildings") {
rl.edges[index].right.buildings.clear();
RoadLinesData::road_edge_side side =
rld->get_line_edge_left(current_line,
index);
side.buildings.clear();
rld->set_line_edge_left(current_line, index,
side);
}
rld->set_line(current_line, rl);
print_line("line updated: " + current_line);
@@ -1327,41 +1350,58 @@ class EdgeEditorHandler {
rl.points[index + 1].origin.distance_to(
rl.points[index].origin) /
2.0f;
set_lot(rl.edges[index].right, pname, dir_offt);
RoadLinesData::road_edge_side side =
rld->get_line_edge_right(current_line,
index);
set_lot(side, pname, dir_offt);
rld->set_line_edge_right(current_line, index,
side);
} else if (pname.begins_with("residental-") ||
pname.begins_with("business-")) {
RoadLinesData::road_edge_side side =
rld->get_line_edge_right(current_line,
index);
struct RoadLinesData::road_edge_side::buildings
b;
b.id = pname;
b.offsets = Vector3();
b.y_rotation = 0.0f;
rl.edges[index].right.buildings.push_back(b);
if (rl.edges[index].right.lot > 0) {
String lot_id =
rl.edges[index].right.lot_type;
if (rl.edges[index]
.right.buildings.size() >
1) {
side.buildings.push_back(b);
if (side.lot > 0) {
String lot_id = side.lot_type;
if (side.buildings.size() > 1) {
const AABB &aabb_lot =
BuildingsData::get_singleton()
->building_aabbs
["lot-" +
lot_id];
bool pack_result = pack_buildings(
aabb_lot,
rl.edges[index]
.right.buildings,
2.0f);
bool pack_result =
pack_buildings(
aabb_lot,
side.buildings,
2.0f);
assert(pack_result);
}
}
rld->set_line_edge_right(current_line, index,
side);
} else if (pname == "clear") {
rl.edges[index].right.lot_type = "";
rl.edges[index].right.lot = 0;
rl.edges[index].right.buildings.clear();
RoadLinesData::road_edge_side side =
rld->get_line_edge_right(current_line,
index);
side.lot_type = "";
side.lot = 0;
side.buildings.clear();
rld->set_line_edge_right(current_line, index,
side);
} else if (pname == "clear-buildings") {
rl.edges[index].right.buildings.clear();
RoadLinesData::road_edge_side side =
rld->get_line_edge_right(current_line,
index);
side.buildings.clear();
rld->set_line_edge_right(current_line, index,
side);
}
rld->set_line(current_line, rl);
rld->update_line_edges();
@@ -1387,8 +1427,8 @@ public:
assert(index >= 0 &&
index < (int)rld->lines(current_line).points.size() - 1);
assert(index >= 0 &&
index < (int)rld->lines(current_line).edges.size());
data = rld->lines(current_line).edges[index].to_dict();
index < (int)rld->get_line_edge_count(current_line));
data = rld->get_line_edge(current_line, index).to_dict();
const Dictionary &left = data["left"], &right = data["right"];
PanelContainer *p = memnew(PanelContainer);
top->call_deferred("add_child", p);
@@ -1551,7 +1591,7 @@ void RoadLinesEditor::create_edge_editor_ui(Control *top)
int index = get_line_index();
if (index < 0)
return;
if ((int)rld->lines(current_line).edges.size() < index)
if ((int)rld->get_line_edge_count(current_line) < index)
return;
print_line("created with index: " + itos(index));
if (edge_editor)

View File

@@ -21,6 +21,7 @@
#include "road_debug.h"
#include "road_lines_data.h"
#include "buildings_data.h"
#include "contours.h"
#include "road_processing.h"
struct side_ref {
@@ -39,23 +40,12 @@ struct wedge {
class DebugGeo : public ImmediateGeometry {
Ref<SpatialMaterial> imm_mat;
int vertex_count;
#if 0
RID im;
bool empty;
AABB aabb;
#endif
public:
DebugGeo()
: ImmediateGeometry()
, vertex_count(0)
{
#if 0
im = RID_PRIME(
VisualServer::get_singleton()->immediate_create());
set_base(im);
empty = true;
#endif
if (!imm_mat.is_valid()) {
imm_mat.instance();
imm_mat->set_flag(
@@ -83,49 +73,6 @@ public:
print_line("total vertex count: " + itos(vertex_count));
vertex_count = 0;
}
#if 0
PoolVector<Face3> get_faces(uint32_t p_usage_flags) const
{
return PoolVector<Face3>();
}
AABB get_aabb() const
{
return aabb;
}
void begin_lines()
{
VisualServer::get_singleton()->immediate_begin(
im, VisualServer::PRIMITIVE_LINES, RID());
}
void end()
{
VisualServer::get_singleton()->immediate_end(im);
}
void set_color(const Color &c)
{
VisualServer::get_singleton()->immediate_color(im, c);
}
void add_vertex(const Vector3 &v)
{
VisualServer::get_singleton()->immediate_vertex(im, v);
if (empty) {
aabb.position = v;
aabb.size = Vector3();
empty = false;
} else
aabb.expand_to(v);
}
void clear()
{
VisualServer::get_singleton()->immediate_clear(im);
empty = true;
}
~DebugGeo()
{
VisualServer::get_singleton()->free(im);
}
#endif
};
static Ref<SpatialMaterial> dbg_mat;
@@ -143,9 +90,6 @@ struct RoadLinesProcessing {
(std::hash<int>()(key.second) << 8);
}
};
std::unordered_map<std::pair<int, int>,
const RoadLinesData::road_edge_side *, side_hash>
sides;
std::unordered_map<std::pair<int, int>, struct side_ref, side_hash>
side_refs;
std::unordered_map<uint32_t, std::vector<struct wedge> > wedges;
@@ -159,9 +103,14 @@ struct RoadLinesProcessing {
singleton = memnew(RoadLinesProcessing);
return singleton;
}
DebugGeo *dbg;
ConfigFile config;
RoadLinesProcessing()
: dbg(nullptr)
{
singleton = this;
Error err = config.load("res://config/stream.conf");
assert(err == OK);
}
void create_nodes(const std::vector<Vector3> &road_lines_nodes)
@@ -397,7 +346,7 @@ out2:;
bool ok = true;
while (e) {
const String &key = e->get();
for (i = 0; i < (int)rld->lines(key).edges.size();
for (i = 0; i < (int)rld->get_line_edge_count(key);
i++) {
if (key == ignore_key && i == ignore_index)
continue;
@@ -428,12 +377,12 @@ out2:;
List<String>::Element *e = keys.front();
while (e) {
const String &key = e->get();
for (i = 0; i < (int)rld->lines(key).edges.size();
for (i = 0; i < (int)rld->get_line_edge_count(key);
i++) {
assert(rld->lines(key).edges[i].left.pmid[0] ==
rld->lines(key).edges[i].right.pmid[0]);
assert(rld->lines(key).edges[i].left.pmid[1] ==
rld->lines(key).edges[i].right.pmid[1]);
assert(rld->get_line_edge_left(key, i).pmid[0] ==
rld->get_line_edge_right(key, i).pmid[0]);
assert(rld->get_line_edge_left(key, i).pmid[1] ==
rld->get_line_edge_right(key, i).pmid[1]);
}
e = e->next();
}
@@ -452,22 +401,30 @@ out2:;
RoadLinesData::road_edge_side left =
rld->get_line_edge_left(key, i);
left.lot = 1;
left.lot_depth = 100.0f;
left.lot_depth_eff = 100.0f;
left.lot_depth = config.get_value(
"road", "lot_depth", 200.0f);
left.lot_depth_eff = config.get_value(
"road", "lot_depth", 200.0f);
rld->set_line_edge_left(key, i, left);
RoadLinesData::road_edge_side right =
rld->get_line_edge_right(key, i);
right.lot = 1;
right.lot_depth = 100.0f;
right.lot_depth_eff = 100.0f;
rld->set_line_edge_left(key, i, right);
right.lot_depth = config.get_value(
"road", "lot_depth", 200.0f);
right.lot_depth_eff = config.get_value(
"road", "lot_depth", 200.0f);
rld->set_line_edge_right(key, i, right);
}
e = e->next();
}
}
/* FIXME: need to generate lots from wedges, not lines (because intersections)
and join lots on the same line segment if they are adjacent and of similar depth
and not too narrow */
void update_lot_depths()
{
int i, j;
#if 0
int i, j, k;
struct line_check {
struct side_ref side;
Vector3 normal;
@@ -475,19 +432,26 @@ out2:;
Vector3 startp;
AABB rect;
};
LocalVector<struct line_check> check_lines;
RoadLinesProcessing *r = RoadLinesProcessing::get_singleton();
if (r->nodes.size() == 0)
return;
DebugGeo *dbg = memnew(DebugGeo);
if (r->nodes.empty())
goto out_skip_end;
// dbg->set_material_override(dbg_mat);
SceneTree::get_singleton()->get_current_scene()->add_child(dbg);
if (!dbg &&
VisualServer::get_singleton()->is_render_loop_enabled()) {
dbg = memnew(DebugGeo);
SceneTree::get_singleton()
->get_current_scene()
->call_deferred("add_child", dbg);
}
print_line("wedges size:" + itos(r->nodes.size()));
dbg->clear();
dbg->begin(Mesh::PRIMITIVE_LINES);
dbg->set_color(Color(1, 0, 0, 1));
dbg->set_color(Color(1, 0, 0, 1));
for (i = 0; i < (int)r->nodes.size(); i++) {
const std::vector<struct wedge> &ws = wedges[i];
int wsize = ws.size();
@@ -511,9 +475,9 @@ out2:;
Vector3 n2 = (w.p[1] - w.y[1]).normalized();
Vector3 n3 = (w.p[2] - w.y[2]).normalized();
mside1.lot_depth_eff =
MAX(mside1.lot_depth_eff, 100.0f);
MAX(mside1.lot_depth_eff, 200.0f);
mside2.lot_depth_eff =
MAX(mside2.lot_depth_eff, 100.0f);
MAX(mside2.lot_depth_eff, 200.0f);
assert(mside1.lot_depth_eff > 0.001);
assert(mside2.lot_depth_eff > 0.001);
struct line_check lc1, lc2;
@@ -543,6 +507,70 @@ out2:;
}
}
assert(check_lines.size() > 0);
for (i = 0; i < (int)check_lines.size(); i++) {
for (j = 0; j < (int)r->nodes.size(); j++) {
const std::vector<struct wedge> &ws = wedges[j];
int wsize = ws.size();
for (k = 0; k < wsize; k++) {
const struct wedge &w = ws[k];
Vector3 p0 = check_lines[i].startp;
Vector3 p1 =
p0 +
check_lines[i].normal *
check_lines[i].depth;
Vector3 p2 = w.p[0];
Vector3 p3 = w.p[1];
Vector3 s, t;
/* samey segments do not intersect */
if (p0.is_equal_approx(p2) &&
p1.is_equal_approx(p3))
continue;
if (p0.is_equal_approx(p3) &&
p1.is_equal_approx(p2))
continue;
/* segments which share a point do not intersect */
if (p0.is_equal_approx(p2))
continue;
if (p0.is_equal_approx(p3))
continue;
if (p1.is_equal_approx(p3))
continue;
if (p1.is_equal_approx(p2))
continue;
assert(!p0.is_equal_approx(p1) &&
!p2.is_equal_approx(p3));
Geometry::get_closest_points_between_segments(
p0, p1, p2, p3, s, t);
if (s.is_equal_approx(p0))
continue;
if (s.is_equal_approx(p1))
continue;
if (t.is_equal_approx(p2))
continue;
if (t.is_equal_approx(p3))
continue;
assert(!s.is_equal_approx(p0));
assert(!s.is_equal_approx(p1));
assert(!t.is_equal_approx(p2));
assert(!t.is_equal_approx(p3));
Vector3 mx(t.x, s.y, t.z);
if (!s.is_equal_approx(mx))
continue;
if (Math::abs(s.y - t.y) < 5.0f) {
if (s.is_equal_approx(mx)) {
float l1 =
p0.distance_to(
s);
check_lines[i]
.depth = MIN(
check_lines[i]
.depth,
l1);
}
}
}
}
}
for (i = 0; i < (int)check_lines.size(); i++) {
Vector3 p0 = check_lines[i].startp;
Vector3 p1 = p0 + check_lines[i].normal *
@@ -645,8 +673,19 @@ out2:;
side1.side);
mside1.lot_depth_eff = check_lines[i].depth;
mside1.lot_depth = mside1.lot_depth_eff;
mside1.lot_points.push_back(p0);
mside1.lot_points.push_back(p1);
int bad_count = 0;
int lot_points = mside1.lot_points.size();
assert(lot_points == 0 || lot_points == 2);
for (j = 0; j < mside1.lot_points.size(); j++) {
if (!mside1.lot_points[j].is_equal_approx(p0))
bad_count++;
if (!mside1.lot_points[j].is_equal_approx(p1))
bad_count++;
}
if (bad_count < 2) {
mside1.lot_points.push_back(p0);
mside1.lot_points.push_back(p1);
}
if (side1.side == 0)
RoadLinesData::get_singleton()
->set_line_edge_left(side1.line_key,
@@ -659,7 +698,116 @@ out2:;
mside1);
}
dbg->end();
dbg->begin(Mesh::PRIMITIVE_LINES);
dbg->set_color(Color(0, 1, 1, 1));
{
List<String> line_keys;
List<String>::Element *line_e;
RoadLinesData *rld = RoadLinesData::get_singleton();
rld->get_road_lines_key_list(&line_keys);
line_e = line_keys.front();
while (line_e) {
const String &key = line_e->get();
print_line("line: " + key);
int edges = rld->get_line_edge_count(key);
for (i = 0; i < edges; i++) {
RoadLinesData::road_edge_side left =
rld->get_line_edge_left(key, i);
RoadLinesData::road_edge_side right =
rld->get_line_edge_right(key,
i);
print_line("edge: " + itos(i) +
" left: lot: " +
itos(left.lot));
print_line("edge: " + itos(i) +
" right: lot: " +
itos(right.lot));
print_line(
"lot_points: left: " +
itos(left.lot_points.size()));
print_line(
"lot_points: right: " +
itos(right.lot_points.size()));
for (j = 0;
j < (int)left.lot_points.size();
j++) {
dbg->add_vertex(
left.lot_points[j] +
Vector3(0, 20, 0));
dbg->add_vertex(
left.lot_points[j] +
Vector3(0, 200, 0));
}
if (left.lot_points.size() == 6) {
int index[] = { 0, 1, 1, 3,
3, 5, 5, 4 };
for (j = 0; j < 8; j++) {
dbg->add_vertex(
left.lot_points
[index[j]] +
Vector3(0, 25,
0));
print_line(
itos(j) + ": " +
left.lot_points[index[j]]
.
operator String());
}
assert(false);
} else if (left.lot_points.size() ==
4) {
int index[] = { 0, 1, 1, 3,
3, 2, 2, 0 };
for (j = 0; j < 8; j++)
dbg->add_vertex(
left.lot_points
[index[j]] +
Vector3(0, 25,
0));
}
for (j = 0;
j < (int)right.lot_points.size();
j++) {
dbg->add_vertex(
right.lot_points[j] +
Vector3(0, 20, 0));
dbg->add_vertex(
right.lot_points[j] +
Vector3(0, 200, 0));
}
if (right.lot_points.size() == 6) {
dbg->add_vertex(
right.lot_points[0] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[1] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[1] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[3] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[3] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[2] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[2] +
Vector3(0, 25, 0));
dbg->add_vertex(
right.lot_points[0] +
Vector3(0, 25, 0));
}
}
line_e = line_e->next();
}
}
dbg->end();
out_skip_end:;
#endif
}
void create_structures()
{
@@ -677,19 +825,21 @@ out_skip_end:;
e = e->next();
continue;
}
if (rld->lines(key).edges.size() !=
rld->lines(key).points.size() - 1) {
if (rld->get_line_edge_count(key) !=
(int)rld->lines(key).points.size() - 1) {
e = e->next();
continue;
}
print_line("line: " + key + " edges count: " +
itos((int)rld->lines(key).edges.size()));
for (i = 0; i < (int)rld->lines(key).edges.size();
itos((int)rld->get_line_edge_count(key)));
for (i = 0; i < (int)rld->get_line_edge_count(key);
i++) {
const RoadLinesData::road_edge &edge =
rld->lines(key).edges[i];
const Vector3 &p0 = edge.left.pmid[0];
const Vector3 &p1 = edge.left.pmid[1];
rld->get_line_edge(key, i);
const RoadLinesData::road_edge_side side =
rld->get_line_edge_left(key, i);
const Vector3 &p0 = side.pmid[0];
const Vector3 &p1 = side.pmid[1];
Vector3 dir = (p1 - p0).normalized();
/* lots */
structures_generated +=
@@ -741,8 +891,6 @@ out_skip_end:;
idx2) ==
edges[idx1].neighbors.end()) {
edges[idx1].neighbors.push_back(idx2);
sides[{ idx1, idx2 }] =
&rld->lines(key).edges[i].left;
side_refs[{ idx1, idx2 }] = { key, i,
0 };
}
@@ -751,8 +899,6 @@ out_skip_end:;
idx1) ==
edges[idx2].neighbors.end()) {
edges[idx2].neighbors.push_back(idx1);
sides[{ idx2, idx1 }] =
&rld->lines(key).edges[i].right;
side_refs[{ idx2, idx1 }] = { key, i,
1 };
}
@@ -833,9 +979,6 @@ out_skip_end:;
edges[k].neighbors.end(),
n1) == edges[k].neighbors.end()) {
edges[k].neighbors.push_back(n1);
assert(sides.find({ n2, n1 }) !=
sides.end());
sides[{ k, n1 }] = sides[{ n2, n1 }];
side_refs[{ k, n1 }] =
side_refs[{ n2, n1 }];
}
@@ -843,7 +986,6 @@ out_skip_end:;
edges[k].neighbors.end(),
n2) == edges[k].neighbors.end()) {
edges[k].neighbors.push_back(n2);
sides[{ k, n2 }] = sides[{ n1, n2 }];
side_refs[{ k, n2 }] =
side_refs[{ n1, n2 }];
}
@@ -851,7 +993,6 @@ out_skip_end:;
edges[n1].neighbors.end(),
k) == edges[n1].neighbors.end()) {
edges[n1].neighbors.push_back(k);
sides[{ n1, k }] = sides[{ n1, n2 }];
side_refs[{ n1, k }] =
side_refs[{ n1, n2 }];
}
@@ -859,7 +1000,6 @@ out_skip_end:;
edges[n2].neighbors.end(),
k) == edges[n2].neighbors.end()) {
edges[n2].neighbors.push_back(k);
sides[{ n2, k }] = sides[{ n2, n1 }];
side_refs[{ n2, k }] =
side_refs[{ n2, n1 }];
}
@@ -1004,6 +1144,108 @@ out_skip_end:;
}
}
}
void find_closed_contours()
{
int i, j;
Contours *contours = Contours::get_singleton();
RoadLinesProcessing *r = RoadLinesProcessing::get_singleton();
if (r->nodes.size() == 0)
return;
struct wedge_data {
int node;
int neighbor_num;
};
std::vector<const struct wedge *> wedges_flat;
std::vector<std::pair<int, int> > wedges_ref;
for (i = 0; i < (int)r->nodes.size(); i++) {
const std::vector<struct wedge> &ws = wedges[i];
for (j = 0; j < (int)ws.size(); j++) {
wedges_flat.push_back(&ws[j]);
wedges_ref.push_back({ i, j });
}
}
std::vector<int> used;
int contour_count = 0;
int base = 0;
while (true) {
std::vector<int> contour;
bool finished = false;
std::pair<int, int> &wref0 = wedges_ref[base];
struct wedge *wbase =
&wedges[wref0.first]
[wref0.second]; /* previous point */
if (contour.empty())
contour.push_back(base);
while (true) {
int added = 0;
for (j = 0; j < (int)wedges_ref.size(); j++) {
if (j == base)
continue;
if (std::find(used.begin(), used.end(),
j) != used.end())
continue;
std::pair<int, int> &wref_prev =
wedges_ref[contour.back()];
std::pair<int, int> &wref =
wedges_ref[j];
struct wedge *wprev =
&wedges[wref_prev.first]
[wref_prev.second]; /* previous point */
struct wedge *wcurrent =
&wedges[wref.first]
[wref.second]; /* current point */
if (wprev->p[2].is_equal_approx(
wcurrent->p[0])) {
contour.push_back(j);
added++;
if (wbase->p[0].is_equal_approx(
wcurrent->p[2])) {
finished = true;
break;
}
}
}
if (finished)
break;
if (added == 0)
break;
}
if (finished) {
int k;
print_line("complete contour");
std::vector<struct wedge *> wedge_contour;
Vector<Vector2> polygon;
for (k = 0; k < (int)contour.size(); k++) {
std::pair<int, int> &wr =
wedges_ref[contour[k]];
wedge_contour.push_back(
&wedges[wr.first][wr.second]);
print_line(itos(k) + ": " +
itos(contour[k]));
Vector3 p1 =
wedges[wr.first][wr.second].p[0];
Vector3 p2 =
wedges[wr.first][wr.second].p[1];
Vector3 p3 =
wedges[wr.first][wr.second].p[2];
polygon.push_back(Vector2(p1.x, p1.z));
polygon.push_back(Vector2(p2.x, p2.z));
polygon.push_back(Vector2(p3.x, p3.z));
used.push_back(contour[k]);
}
if (Geometry::is_polygon_clockwise(polygon))
contours->get_singleton()
->wedge_contours.push_back(
wedge_contour);
contour.clear();
contour_count++;
} else
contour.clear();
base++;
if (base >= (int)wedges_ref.size())
break;
}
}
~RoadLinesProcessing()
{
}
@@ -1042,7 +1284,8 @@ out_skip_end:;
sort_neighbors();
wedges.clear();
build_wedges(wedges);
update_lot_depths();
find_closed_contours();
// update_lot_depths();
ImmediateGeometry *d = rld->get_debug_node();
d->clear();
if (debug_flags & 1) {
@@ -1269,7 +1512,6 @@ public:
out_arrays[ArrayMesh::ARRAY_INDEX];
out_index_orig.append_array(out_index);
out_arrays[ArrayMesh::ARRAY_INDEX] = out_index_orig;
// out_arrays[ArrayMesh::ARRAY_INDEX] = indices;
}
void init_surface(Array &surface)
@@ -1363,12 +1605,6 @@ public:
lane.use_mesh = use_mesh;
assert(use_mesh.length() > 0);
assert(lane.use_mesh.length() > 0);
#if 0
lane.xform1 = Transform(Basis(), lane.p[0]);
lane.xform_m1 = Transform(Basis(), lane.p[1]);
lane.xform_m2 = Transform(Basis(), lane.p[1]);
lane.xform2 = Transform(Basis(), lane.p[2]);
#endif
Transform xform1 =
Transform().looking_at(params.dir1, Vector3(0, 1, 0));
xform1.origin = lane.p[0];
@@ -1563,10 +1799,6 @@ public:
wedge.side2_ref.side);
print_line("m1: " + String::num(mside1.lot_depth_eff));
print_line("m2: " + String::num(mside2.lot_depth_eff));
// mside1.lot_depth_eff = 100.0f;
// mside2.lot_depth_eff = 100.0f;
// assert(mside1.lot_depth_eff >= 0.98f);
// assert(mside2.lot_depth_eff >= 0.98f);
/* for each lane */
for (k = 0; k < (int)lanes.size(); k++) {
std::vector<Array> surfaces;
@@ -1682,17 +1914,19 @@ public:
out_surfaces[h], 0.0f);
} else if (k == params.nlanes + 1 &&
mside1.lot > 0) { /* lot */
// assert(mside1.lot_depth_eff >= 0.98f);
build_split_segment(
lanes[k].xform1,
lanes[k].xform_m1,
mside1.lot_depth_eff,
MIN(mside1.lot_depth_eff,
mside2.lot_depth_eff), // mside1.lot_depth_eff,
// get_lot_depth(wedge),
surfaces[h], out_surfaces[h],
0.0f,
get_split_level(wedge) + 1);
if (!Contours::get_singleton()
->is_in_closed_contour(
&wedge))
build_split_segment(
lanes[k].xform1,
lanes[k].xform_m1,
mside1.lot_depth_eff,
MIN(mside1.lot_depth_eff,
mside2.lot_depth_eff),
surfaces[h],
out_surfaces[h], 0.0f,
get_split_level(wedge) +
1);
} else if (k <= params.nlanes) /* normal lane */
build_segment(lanes[k].xform1,
@@ -1759,14 +1993,17 @@ public:
"m2: " +
String::num(
mside2.lot_depth_eff));
// assert(mside2.lot_depth_eff >= 0.98f);
build_split_segment(
lanes[k].xform_m2,
lanes[k].xform2, 100.0f,
100.0f, // get_lot_depth(wedge),
// mside2.lot_depth_eff,
surfaces[h], out_surfaces[h],
0.0f, get_split_level(wedge));
if (!Contours::get_singleton()
->is_in_closed_contour(
&wedge))
build_split_segment(
lanes[k].xform_m2,
lanes[k].xform2,
get_lot_depth(wedge),
mside2.lot_depth_eff,
surfaces[h],
out_surfaces[h], 0.0f,
get_split_level(wedge));
} else if (k <= params.nlanes) /* normal lane */
build_segment(lanes[k].xform_m2,
lanes[k].xform2,
@@ -1788,8 +2025,6 @@ public:
int surf_count = road_meshes[center].arrays.size();
out_surfaces.resize(surf_count);
out_materials.resize(surf_count);
// Transform mesh_xform =
// Transform().rotated(Vector3(0, 1, 0), Math_PI);
for (i = 0; i < (int)wedges.size(); i++) {
build_wedge_mesh(wedges[i], center, mid, edge, lot,
out_surfaces, out_materials);