Quality of life with road lines edge data (lots, buildings, etc.)

This commit is contained in:
2025-02-12 05:50:12 +03:00
parent 2780fd300a
commit b56103930c
24 changed files with 17399 additions and 2212 deletions

View File

@@ -17,6 +17,7 @@
#include "from_string.h"
#include "road_debug.h"
#include "road_lines_data.h"
#include "buildings_data.h"
#include "road_processing.h"
struct wedge {
@@ -53,6 +54,328 @@ struct RoadLinesProcessing {
memcpy(nodes.data(), road_lines_nodes.data(),
sizeof(Vector3) * road_lines_nodes.size());
}
Transform get_structure_transform(Vector3 p0, Vector3 p1, Vector3 dir,
Vector3 offset_n, float offset,
float dir_offset, float y_rotation,
float y_offset)
{
Transform xform(Basis(), p0 + dir * dir_offset +
offset_n * offset +
Vector3(0, 1, 0) * y_offset);
Transform rot(Basis().rotated(Vector3(0, 1, 0),
Math::deg2rad(y_rotation)),
Vector3());
xform.set_look_at(xform.origin, xform.origin + dir * dir_offset,
Vector3(0, 1, 0));
xform = xform * rot;
return xform;
}
void create_building_structure(const BuildingsData::building &b)
{
assert(b.key.begins_with("road__"));
assert(b.id.length() > 0);
assert(b.key.length() > 0);
if (BuildingsData::get_singleton()->has_building(b.key)) {
BuildingsData::get_singleton()->remove_scene_item(
b.id, b.key);
BuildingsData::get_singleton()->destroy_building(b.key);
}
BuildingsData::get_singleton()->create_building(b);
if (!BuildingsData::get_singleton()->has_scene(b.id))
BuildingsData::get_singleton()->create_scene_data(
b.id, b.key);
else
BuildingsData::get_singleton()->add_scene_item(b.id,
b.key);
print_line("created building: " + b.key);
print_line("at: " + (b.xform.origin.operator String()));
}
int create_sideroads(const String &line_key, int edge_no,
const RoadLinesData::road_edge &edge,
const Vector3 &p0, const Vector3 &p1,
const Vector3 &dir, const Vector3 left_n,
const Vector3 &right_n)
{
int structures_generated = 0;
if (edge.left.sideroad > 0) {
Transform xform = get_structure_transform(
p0, p1, dir, left_n, edge.left.sideroad_offset,
edge.left.sideroad_dir_offset,
edge.left.sideroad_y_rotation,
edge.left.sideroad_y_offset);
BuildingsData::building b;
b.key = "road__" + line_key + "__sideroad__" +
itos(edge_no) + "__left__sideroad-" +
edge.left.sideroad_type;
b.id = "sideroad-" + edge.left.sideroad_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
if (edge.left.sideroad_type.length() == 0) {
print_error("bad sideroad");
goto out;
}
create_building_structure(b);
structures_generated++;
out:;
}
if (edge.right.sideroad > 0) {
Transform xform = get_structure_transform(
p0, p1, dir, right_n,
edge.right.sideroad_offset,
edge.right.sideroad_dir_offset,
edge.right.sideroad_y_rotation,
edge.right.sideroad_y_offset);
BuildingsData::building b;
b.key = "road__" + line_key + "__sideroad__" +
itos(edge_no) + "__right__sideroad-" +
edge.right.sideroad_type;
b.id = "sideroad-" + edge.right.sideroad_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
if (edge.right.sideroad_type.length() == 0) {
print_error("bad sideroad");
goto out2;
}
create_building_structure(b);
structures_generated++;
out2:;
}
return structures_generated;
}
int
create_line_building(const String &line_key, int edge_id,
const Transform &xform,
const struct RoadLinesData::road_edge_side &side,
const String &side_name)
{
int building_no;
int structures_generated = 0;
for (building_no = 0; building_no < (int)side.buildings.size();
building_no++) {
const struct RoadLinesData::road_edge_side::buildings
&building = side.buildings[building_no];
String id = side.buildings[building_no].id;
id = id.strip_edges();
if (id.length() == 0)
continue;
Transform rot(
Basis().rotated(
Vector3(0, 1, 0),
Math::deg2rad(building.y_rotation)),
building.offsets);
Transform building_xform = xform * rot;
BuildingsData::building bbuilding;
bbuilding.id = id;
bbuilding.key = "road__" + line_key + "__lot__" +
itos(edge_id) + "__" + side_name +
"__" + itos(building_no) +
"__building-" + building.id;
bbuilding.generated = true;
bbuilding.line_name = line_key;
bbuilding.key_hash = bbuilding.key.hash64();
bbuilding.pattern_id = 0;
bbuilding.xform = building_xform;
bbuilding.worktime[0] = 0;
bbuilding.worktime[1] = 23;
create_building_structure(bbuilding);
structures_generated++;
}
return structures_generated;
}
int create_lots(const String &line_key, int edge_no,
const RoadLinesData::road_edge &edge, const Vector3 &p0,
const Vector3 &p1, const Vector3 &dir,
const Vector3 left_n, const Vector3 &right_n)
{
int structures_generated = 0;
if (edge.left.lot > 0) {
Transform xform = get_structure_transform(
p0, p1, dir, left_n, edge.left.lot_offset,
edge.left.lot_dir_offset,
edge.left.lot_y_rotation,
edge.left.lot_y_offset);
BuildingsData::building b;
b.key = "road__" + line_key + "__lot__" +
itos(edge_no) + "__left__lot-" +
edge.left.lot_type;
b.id = "lot-" + edge.left.lot_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
create_building_structure(b);
structures_generated++;
if (edge.left.buildings.size() > 0) {
structures_generated += create_line_building(
line_key, edge_no, xform, edge.left,
"left");
}
}
if (edge.right.lot > 0) {
Transform xform = get_structure_transform(
p0, p1, dir, right_n, edge.right.lot_offset,
edge.right.lot_dir_offset,
edge.right.lot_y_rotation,
edge.right.lot_y_offset);
BuildingsData::building b;
b.key = "road__" + line_key + "__lot__" +
itos(edge_no) + "__right__lot-" +
edge.right.lot_type;
b.id = "lot-" + edge.right.lot_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
create_building_structure(b);
structures_generated++;
if (edge.right.buildings.size() > 0) {
structures_generated += create_line_building(
line_key, edge_no, xform, edge.right,
"right");
}
}
return structures_generated;
}
int create_transit_stops(const String &line_key, int edge_no,
const RoadLinesData::road_edge &edge,
const Vector3 &p0, const Vector3 &p1,
const Vector3 &dir, const Vector3 left_n,
const Vector3 &right_n)
{
int j;
int structures_generated = 0;
float l = p0.distance_to(p1);
if (edge.left.transit_stop_count > 0) {
print_line("Creating transit stops on the left");
float t = 0.0f;
float m =
l / ((float)(edge.left.transit_stop_count + 1));
for (j = 0; j < edge.left.transit_stop_count; j++) {
Transform xform = get_structure_transform(
p0, p1, dir, left_n,
edge.left.transit_stop_offset,
t + edge.left.transit_stop_dir_offset,
edge.left.transit_stop_y_rotation,
0.0f);
BuildingsData::building b;
b.key = "road__" + line_key +
"__transit_stop__" + itos(edge_no) +
"__" + itos(j) + "__left__" +
edge.left.transit_stop_type;
b.id = edge.left.transit_stop_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
create_building_structure(b);
t += m;
structures_generated++;
}
}
if (edge.right.transit_stop_count > 0) {
print_line("Creating transit stops on the right");
float t = 0.0f;
float m = l /
((float)(edge.right.transit_stop_count + 1));
for (j = 0; j < edge.right.transit_stop_count; j++) {
Transform xform = get_structure_transform(
p0, p1, dir, right_n,
edge.right.transit_stop_offset,
t + edge.right.transit_stop_dir_offset,
edge.right.transit_stop_y_rotation,
0.0f);
BuildingsData::building b;
b.key = "road__" + line_key +
"__transit_stop__" + itos(edge_no) +
"__" + itos(j) + "__right__" +
edge.right.transit_stop_type;
b.id = edge.right.transit_stop_type;
b.generated = true;
b.line_name = line_key;
b.key_hash = b.key.hash64();
b.pattern_id = 0;
b.xform = xform;
b.worktime[0] = 0;
b.worktime[1] = 23;
create_building_structure(b);
t += m;
structures_generated++;
}
}
return structures_generated;
}
void create_structures()
{
List<String> keys;
RoadLinesData *rld = RoadLinesData::get_singleton();
rld->get_road_lines_key_list(&keys);
List<String>::Element *e = keys.front();
print_line("create structures");
print_line("road_lines: " + itos(keys.size()));
int structures_generated = 0;
while (e) {
const String &key = e->get();
int i;
if (rld->lines(key).points.size() < 2) {
e = e->next();
continue;
}
if (rld->lines(key).edges.size() !=
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();
i++) {
const RoadLinesData::road_edge &edge =
rld->lines(key).edges[i];
const Vector3 &p0 =
rld->lines(key).points[i].origin;
const Vector3 &p1 =
rld->lines(key).points[i + 1].origin;
Vector3 dir = (p1 - p0).normalized();
Vector3 d = dir;
Vector3 left_n = Vector3(0, 1, 0).cross(d);
Vector3 right_n = -left_n;
/* lots */
structures_generated +=
create_lots(key, i, edge, p0, p1, dir,
left_n, right_n);
/* sideroads */
structures_generated +=
create_sideroads(key, i, edge, p0, p1,
dir, left_n, right_n);
/* bus stops */
structures_generated += create_transit_stops(
key, i, edge, p0, p1, dir, left_n,
right_n);
}
e = e->next();
}
print_line("structures generated: " +
itos(structures_generated));
}
void create_edges()
{
int i;
@@ -236,7 +559,7 @@ struct RoadLinesProcessing {
if (Vector2(q.x, q.z)
.distance_squared_to(
Vector2(r.x, r.z)) <
0.005f)
0.1f)
pr = q.linear_interpolate(r,
0.5f);
else {
@@ -819,6 +1142,7 @@ RoadMeshProcessing *RoadMeshProcessing::singleton;
void RoadProcessing::road_setup(Node *target, int debug_flags)
{
RoadLinesProcessing::get_singleton()->create_structures();
RoadLinesProcessing::get_singleton()->set_debug_flags(debug_flags);
RoadLinesProcessing::get_singleton()->road_setup();
RoadMeshProcessing::get_singleton()->create_road_meshes(target);